<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <link rel="stylesheet" href="test.css">
  <title>Zepto Core unit tests</title>
  <script src="../vendor/evidence.js"></script>
  <script src="evidence_runner.js"></script>
  <script>
    // avoid caching
    (function(){
      function load(scripts){
        scripts.split(' ').forEach(function(script){
          document.write('<script src="../src/'+script+'.js?'+(+new Date)+'"></scr'+'ipt>')
        })
      }

      load('zepto event ie')
    })()
  </script>
  <style>
    #get_style_element {
      font-size: 48px;
      color: black;
    }
  </style>
</head>
<body>
  <h1>Zepto Core unit tests</h1>
  <p id="results">
    Running… see browser console for results
  </p>
  <div id="fixtures">

  <div id="some_element"></div>
  <p>
    <span class="yay">yay</span>
    <span></span>
    <span class="nay" id="nay">nay</span>
  </p>

  <div id="toggle_element"></div>

  <div id="get_style_wrapper" style="font-size: 16px;">
    <div id="get_style_element">Derp</div>
  </div>

  <div class="replacewith">
    <div class="inner first">Hello</div>
    <div class="inner second">And</div>
    <div class="inner third">Goodbye</div>
  </div>

  <div id="attr_1" data-id="someId1" data-name="someName1"></div>
  <div id="attr_2" data-id="someId2" data-name="someName2"></div>
  <div id="attr_remove" data-name="boom"></div>
  <form><input id="attr_val" value="Hello World"></form>

  <div id="data_attr" data-foo="bar" data-foo-bar="baz" data-empty></div>

  <form id="attr_with_text_input">
  </form>

  <label for="prop_test2" id="prop_test1"></label>
  <input id="prop_test2" type="text" tabindex="-1" maxlength="10" readonly class="propTest" />
  <table id="prop_test3" cellspacing="10" cellpadding="5">
    <tr>
      <td id="prop_test4" rowspan="2"></td>
      <td></td>
    </tr>
    <tr>
      <td></td>
    </tr>
    <tr>
      <td id="prop_test5" colspan="2"></td>
    </tr>
  </table>
  <img id="prop_test6" usemap="#imgMap" />
  <map name="imgMap">
  </map>
  <div id="prop_test7" contenteditable="true"></div>

  <div class="htmltest" id="htmltest1"></div>
  <div class="htmltest" id="htmltest2"></div>
  <div id="htmltest3"></div>
  <table id="htmltest4"></table>

  <div id="texttest1" class="texttest"><span>Here <strong>is</strong> some text</span></div>
  <div id="texttest2" class="texttest">And <em>some more</em></div>
  <div id="texttest3" class="texttest"></div>

  <div id="beforeafter_container"><div id="beforeafter"></div></div>
  <div id="appendtoprependto_container"><div id="appendtoprependto"></div></div>
  <div id="insertbeforeinsertafter_container"><div id="insertbeforeinsertafter"></div></div>

  <div id="empty_test">
    <div id="empty_1"></div>
    <div id="empty_2"></div>
    <div id="empty_3"></div>
    <span id="empty_4">test</span>
  </div>

  <p id="find1">
    <span class="findme">1</span>
    <span class="findme">2</span>
    <b>3<span class="findme">4</span></b>
    <span class="findme">5<span>6</span></span>
  </p>

  <p id="find2">
    <span>1</span>
    <span>2</span>
    <span>3<span>4</span></span>
    <span>5<span>6</span></span>
  </p>

  <div id="eachtest">
    <span></span><b></b><br>
  </div>

  <div style="position:absolute;width:100px;height:50px" id="offset">test</div>

  <ul id="parents">
    <li id="li1">
      <ul id="nested">
        <li id="li2">one</li>
        <li>two</li>
        <li>three</li>
      </ul>
      <ul>
        <li></li>
      </ul>
    </li>
  </ul>

  <ul id="childrenTest">
    <li class="child one"><a class="childOfOne" href="#">gchild1</a></li>
    <li class="child two"><a class="childOfTwo" href="#">gchild2</a></li>
    <li class="child three"><a class="childOfThree" href="#">gchild3</a></li>
    <li class="child four"><a class="childOfFour" href="#">gchild4</a></li>
  </ul>

  <ul id="contentsTest">1<span>2</span><span id="contentsEmptyTest"></span></ul>

   <ul id="siblingsTest">
    <li class="child one"><span class="b"></span><em></em><b></b></li>
    <li class="child two"><span class="c"></span><em></em><b></b></li>
    <li class="child three"><span class="d"></span><em></em><b></b></li>
    <li class="child four"><span class="e"></span></li>
  </ul>

  <ul id="notTest">
    <li class="child one"><span class="b"></span></li>
    <li class="child two"><span class="c"></span></li>
    <li class="child three"><span class="d" id="notTestExclude"></span></li>
    <li class="child four"><span class="e"></span></li>
  </ul>

  <div id="addTest">
    <span class="add_span"></span>
    <span class="add_span"></span>
    <span class="add_span"></span>
    <span class="add_span_exclude"></span>
    <div id="addTestDiv"></div>
  </div>

  <style>
    .hidden {
      display: none;
    }

    #show_hide_span1,
    #show_hide_span2 {
      display: block;
    }

    #show_hide_div1 {
      display: inline-block;
    }
  </style>

  <div id="show_hide_div1" style="display:none"></div>
  <div id="show_hide_div2" class="hidden"></div>
  <div id="show_hide_div3"></div>

  <span id="show_hide_span1" style="display:none"></span>
  <span id="show_hide_span2" class="hidden"></span>
  <span id="show_hide_span3"></span>

  <div class="filtertest" id="filtertest1"></div>
  <div class="filtertest" id="filtertest2"></div>

  <div id="delegate_test"><span class="first-level"><span class="second-level">hi</span></span></div>
  <div id="undelegate_test"><span class="first-level"><span class="second-level">hi</span></span></div>

  <div id="delegate_blur_test"><input type="text"></div>
  <div id="delegate_focus_test"><input type="text"></div>

  <div id="another_element"></div>

  <div id="namespace_test"></div>

  <input type="text" id="BooleanInput" required />

  <form id="some_form"></form>

  <div class="replace_test_div">test</div>

  <div id="wrap_test"><span>hi</span><a></a><span>hello</span></div>

  <div id="wrapall_test"><b></b><span>hi</span><span>hello</span><i></i></div>

  <div id="wrapinner_test">1<span>2</span><span id="wrapinner_empty_test"></span></div>

  <div id="unwrap_test">
    <div class="unwrap_one"><b><span></span></b></div>
    <div class="unwrap_two"><b><span>1</span><span>2</span></b></div>
  </div>

  <div id="slice_test">
    <div class="slice1"></div>
    <div class="slice2"></div>
    <div class="slice3"></div>
  </div>

  <div id="eq_test">
    <div class="eq0"></div>
    <div class="eq1"></div>
    <div class="eq2"></div>
  </div>

  <div id="end_test">
    <div class="end_one"><b><span></span></b></div>
    <div class="end_two"><b><span>1</span><span>2</span></b></div>
  </div>

  <div id="andself_test">
    <div class="one"></div>
    <div class="two"></div>
    <div class="three"></div>
    <div class="four"></div>
  </div>

  <div id="index_test">
    <div class="index0"></div>
    <div class="index1"></div>
  </div>

  <div id="trigger_handler">
    <form method="get">
    </form>
  </div>

  <svg></svg>

  <iframe src="fixtures/iframe_document.html"></iframe>

  <iframe id="link_target_iframe" name="link_target_iframe" width="10" height="10"></iframe>
  <a id="link_that_will_be_prevented" href="fixtures/iframe_document.html" target="link_target_iframe"></a>


  </div><!-- fixtures -->

  <script>
  (function(){

    function click(el){
      var event = document.createEvent('MouseEvents')
      event.initMouseEvent('click', true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null)
      el.dispatchEvent(event)
    }

    function mousedown(el){
      var event = document.createEvent('MouseEvents')
      event.initMouseEvent('mousedown', true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null)
      el.dispatchEvent(event)
    }

    function outerHTML(node) {
      return node.outerHTML || (function(n) {
        var div = document.createElement('div')
        div.appendChild(n.cloneNode(true))
        var html = div.innerHTML
        div = null
        return html
      })(node)
    }

    var globalVarSetFromReady = ""
    $(document).ready(function(){ globalVarSetFromReady = 'hi!' })

    var globalVarSetFromReady2 = ""
    $(function(){ globalVarSetFromReady2 = 'hi!' })

    var globalVarSetFromReady3 = ""
    $(document).on('ready', function(){ globalVarSetFromReady3 = 'hi!' })

    var globalVarSetFromReady4 = ""
    $(document).on('foo ready bar', function(){ globalVarSetFromReady4 = 'hi!' })

    Evidence.Assertions.assertSame = function(expected, actual, message) {
      var expectedKeyCount = 0, actualKeyCount = 0, key, passed = true
      for (key in expected) expectedKeyCount++
      for (key in actual) actualKeyCount++

      if (expectedKeyCount == actualKeyCount)
        for (key in expected)
          passed &= expected[key] == actual[key]
      else
        passed = false

      this._assertExpression(passed, message || 'Failed assertion.',
        'Expected %o to be the same as %o.', actual, expected)
    }

    Evidence.Assertions.assertLength = function(expected, object, message) {
      var actual = object.length
      this._assertExpression(expected === actual, message || 'Failed assertion.',
        'Expected length %d, got %d.', expected, actual)
    }

    Evidence.Assertions.assertEqualCollection = function(expectedCollection, actualCollection, message) {
      var expected = expectedCollection, actual = actualCollection,
          passed = expected.length == actual.length

      if (typeof expected.get == 'function') expected = expected.get()
      if (typeof actual.get == 'function') actual = actual.get()

      if (passed) for (var i=0; i<expected.length; i++) passed &= expected[i] == actual[i]

      this._assertExpression(passed, message || 'Failed assertion.',
        'Expected %o, got %o.', expected, actual)
    }

    Evidence('ZeptoTest', {

      testIsFunction: function(t) {
        t.assertTrue($.isFunction(function(){}))
        t.assertTrue($.isFunction(new Function()))

        var f1 = function(){}
        function f2(){}

        t.assertTrue($.isFunction(f1))
        t.assertTrue($.isFunction(f2))

        t.assertFalse($.isFunction())
        t.assertFalse($.isFunction(undefined))
        t.assertFalse($.isFunction({}))
        t.assertFalse($.isFunction(new Object()))
        t.assertFalse($.isFunction(null))
        t.assertFalse($.isFunction([]))
        t.assertFalse($.isFunction(1))
        t.assertFalse($.isFunction('a'))
        t.assertFalse($.isFunction(new Date()))
        t.assertFalse($.isFunction(window))
        t.assertFalse($.isFunction($('body')))
      },

      testIsPlainObject: function(t) {
        t.assertTrue($.isPlainObject(new Object()), 'Object is plain object')
        t.assertTrue($.isPlainObject({}), '{} is plain object')
        t.assertTrue($.isPlainObject({one : 1}), '{one : 1} is plain object')
        t.assertTrue($.isPlainObject({one : 1, two: [1,2]}), '{one : 1, two: [1,2]} is plain object')

        t.assertFalse($.isPlainObject(new Array()), 'Array object is not plain object')
        t.assertFalse($.isPlainObject([]), '[] is not plain object')
        t.assertFalse($.isPlainObject(null), 'null is not plain object')
        t.assertFalse($.isPlainObject(), 'undefined is not plain object')
        t.assertFalse($.isPlainObject(new String()), 'empty String object is not plain object')
        t.assertFalse($.isPlainObject(new String('moe')), 'String object is not plain object')
        t.assertFalse($.isPlainObject(''), 'the empty string is not plain object')
        t.assertFalse($.isPlainObject('moe'), 'a string is not plain object')
        t.assertFalse($.isPlainObject(new RegExp('test')), 'RegExp object is not plain object')
        t.assertFalse($.isPlainObject(/test/), 'regex is not plain object')
        t.assertFalse($.isPlainObject(new Boolean(true)), 'Boolean object is not plain object')
        t.assertFalse($.isPlainObject(true), 'a boolean is not plain object')
        t.assertFalse($.isPlainObject(new Number(2)), 'Number object is not plain object')
        t.assertFalse($.isPlainObject(2), 'a number is not plain object')
        t.assertFalse($.isPlainObject(new Function()), 'Function object is not plain object')
        t.assertFalse($.isPlainObject(function() {}), 'a function is not plain object')
        t.assertFalse($.isPlainObject(new Date()), 'Date object is not plain object')

        t.assertFalse($.isPlainObject(window), 'window is not a plain object')
        t.assertFalse($.isPlainObject($("html")[0]), 'html node is not a plain object')

        var F = function(){}, obj
        F.prototype = {'a':1}
        obj = new F()
        t.assertFalse($.isPlainObject(obj), 'function with prototype is not a plain object')
      },

      testIsWindow: function(t){
        t.assertFalse($.isWindow())
        t.assertFalse($.isWindow({}))
        t.assertFalse($.isWindow(document.body))
        t.assertTrue($.isWindow(window))
        t.assertTrue($.isWindow($('iframe').get(0).contentWindow))
      },

      // test to see if we augment iOS 3.2 with String#trim()
      testTrim: function(t){
        t.assertEqual("blah", " blah ".trim())
        t.assertIdentical("", $.trim(undefined))
        t.assertIdentical("", $.trim(null))
        t.assertIdentical("", $.trim(""))
        t.assertIdentical("0", $.trim(0))
      },

      testCamelCase: function(t){
        t.assertEqual("hello", $.camelCase("hello"))
        t.assertEqual("HELLO", $.camelCase("HELLO"))
        t.assertEqual("helloNiceWorld", $.camelCase("hello-nice-world"))
        t.assertEqual("helloWorld", $.camelCase("helloWorld"))
      },

      testExtend: function(t){
        t.assertSame({}, $.extend({}))
        t.assertSame(
          {a: "b", c: "d", e: "f"},
          $.extend({a: "1", e: "f"}, {a: "b", c: "d"})
        )
        var obj = {}
        t.assertIdentical(obj, $.extend(obj, {a: 1}))
        t.assertEqual(1, obj.a)

        obj = {}
        t.assertIdentical(obj, $.extend(obj, {a: 1}, {b: 2}))
        t.assertEqual(2, obj.b)

        // undefined values are not copied over
        t.assertSame({a:1}, $.extend({a:1}, {b:undefined}))

        // shallow by default
        obj = $.extend({ a:{b:"c"} }, { a:{d:"e"} })
        t.assertSame({d:"e"}, obj.a)
      },

      testExtendDeep: function(t){
        var obj = { a:{b:"c", x:{y:"z"}} }
        $.extend(true, obj, { a:{d:"e"} }, { a:{b:"B", f:"g", x:{q:"x"}} })

        t.assertEqual('a', Object.keys(obj).join(','))
        t.assertEqual('b,d,f,x', Object.keys(obj.a).sort().join(','))
        t.assertEqual('B', obj.a.b)
        t.assertEqual('e', obj.a.d)
        t.assertEqual('g', obj.a.f)
        t.assertEqual('z', obj.a.x.y)
        t.assertEqual('x', obj.a.x.q)

        // creates non-existing keys on target object
        obj = {}
        $.extend(true, obj, { a:{b:"c"} })
        t.assertEqual('a', Object.keys(obj).join(','))
        t.assertEqual('c', obj.a.b)

        // skips iterating over DOM elements
        obj = {}
        var dom = $('#some_element').get(0)
        $.extend(true, obj, { element: dom })
        t.assertIdentical(dom, obj.element)

        // can override DOM element
        $.extend(true, obj, { element:{a:'b'} })
        t.assertEqual('b', obj.element.a)

        // deep copy with array
        obj = {}
        var initial = { array: [1,2,3,4], object:{a:{b:["c","d"]}} }
        $.extend(true, obj, initial)
        t.assertTrue($.isArray(obj.array))
        t.assertEqual(JSON.stringify(obj), JSON.stringify(initial))
        t.refuteIdentical(obj, initial)
        t.refuteIdentical(obj.array, initial.array)
        t.refuteIdentical(obj.object, initial.object)
        t.refuteIdentical(obj.object.a, initial.object.a)
        t.refuteIdentical(obj.object.a.b, initial.object.a.b)
      },

      testExtensionAPI: function(t) {
        t.assert('init' in $.zepto)
        t.assert('fragment' in $.zepto)
        t.assert('Z' in $.zepto)
        t.assert('isZ' in $.zepto)

        // redefine Z and log some debug information
        var oldZ = $.zepto.Z, calls = []
        $.zepto.Z = function Z(dom, selector) {
          var value = oldZ(dom, selector)
          calls.push(dom)
          return value
        }

        // now select some stuff
        var Z1 = $(''), Z2 = $('#find1 .findme')

        // check if $.fn methods are still there
        t.assert('pluck' in Z1)
        t.assert('width' in Z2)

        // two calls should be logged
        t.assertLength(2, calls)

        // restore old Z
        $.zepto.Z = oldZ
        var Z3 = $('')
        t.assertLength(2, calls)

        t.assertFalse($.zepto.isZ())
        t.assertFalse($.zepto.isZ([]))
        t.assertTrue($.zepto.isZ($('body')))
      },

      testDollar: function(t){
        var expectedElement = document.getElementById('some_element')

        t.assertLength(1, $('#some_element'))
        t.assertEqual(expectedElement, $('#some_element').get(0))
        t.assertEqual(expectedElement, $(expectedElement).get(0))

        t.assertLength(4, $('p'))
        t.assertLength(1, $('p > span.yay'))
      },

      testDollarUnique: function(t){
        t.refuteIdentical($('#some_element'), $('#some_element'))
        t.refuteIdentical($('#nonexistent'), $('#nonexistent'))
      },

      testDollarWithNil: function(t){
        t.assertLength(0, $(null))
        t.assertLength(0, $(undefined))
        t.assertLength(0, $(false))
        t.assertLength(0, $(''))
        t.assertLength(0, $('#'))

        var Z1 = $(null), Z2 = $(null)
        t.assert(Z1 !== Z2)
      },

      testDollarWithNonDOM: function(t){
        var zepto = $(['a', 'b', 'c'])
        t.assertLength(3, zepto)
        t.assertEqualCollection(['a', 'b', 'c'], zepto)

        t.assert($({}))
        t.assertTrue($({ a: true })[0].a)

        // Plain objects wrapped by a Zepto collection
        // should still refer to the original object
        // This is required for events on plain objects
        var plainObject = { a: 1 }
        $(plainObject).get(0).a = 2
        t.assertEqual(2, plainObject.a)
        t.assertEqual(2, $(plainObject).get(0).a)
      },

      testGetWithoutIndex: function(t){
        var zepto = $('#find1 .findme')
        var array = zepto.get()
        t.assertFalse(zepto === array)
        t.assertTrue($.isArray(array))
        t.assertTrue(array.pop === ([]).pop)
      },

      testGetWithIndex: function(t){
        var zepto = $('#find1 .findme')
        t.assertEqual(zepto[0], zepto.get(0))
        t.assertEqual(zepto[zepto.length - 1], zepto.get(-1))
        t.assertUndefined(zepto.get(zepto.length))
      },

      testSize: function(t){
        t.assertEqual(4, $('#find1 .findme').size())
      },

      testDollarWithMultipleInstances: function(t){
        var instance1 = $('#some_element'),
            instance2 = $('p')

        t.assertLength(1, instance1)
        t.assertLength(4, instance2)
        t.refuteIdentical(instance1.get(0), instance2.get(0))
      },

      testDollarWithArrays: function(t){
        var element = document.getElementById('some_element')

        var z1 = $([element])
        t.assertLength(1, z1)
        t.assertEqual(element, z1.get(0))

        var z2 = $([element, null, undefined])
        t.assertLength(1, z2)
        t.assertEqual(element, z2.get(0))

        var z3 = $([null, element, null])
        t.assertLength(1, z3)
        t.assertEqual(element, z3.get(0))
      },

      testDollarWithContext: function(t){
        // Zepto object
        var zepto = $('p#find1, #find2')
        t.assertLength(11, $('span', zepto))

        // DOM Element
        var domElement = document.getElementById('find1')
        t.assertLength(4, $('span.findme', domElement))

        // Selector with DOM Element Context
        var domElement = document.getElementById('find1');
        t.assertLength(4, $('span.findme', domElement));

        // DOM Element with DOM Element Context
        t.assertLength(1, $(domElement, domElement));
      },

      testDollarWithDocument: function(t){
        var z = $(document)
        t.assertLength(1, z)
        t.assertEqual('', z.selector)
      },

      testDollarWithAppcache: function(t){
        if ('applicationCache' in window) {
          var z = $(window.applicationCache)
          t.assertLength(1, z)
          t.assertIdentical(window.applicationCache, z.get(0))
          t.assertEqual('', z.selector)
        }
      },

      testDollarWithDocumentFragment: function(t){
        var documentFragment = $(document.createDocumentFragment())
        t.assertLength(1, documentFragment)
        t.assertEqual(Node.DOCUMENT_FRAGMENT_NODE, documentFragment.get(0).nodeType)
      },

      testDollarWithElementInIframe: function(t){
        var iframe = $('#fixtures iframe').get(0),
            iframeWin = iframe.contentWindow,
            iframeDoc = iframe.contentDocument,
            iframeBody = iframeDoc.body,
            iframeEl = $(iframeBody).find('b')

        t.assertIdentical(iframeWin, $(iframeWin).get(0))
        t.assertIdentical(iframeDoc, $(iframeDoc).get(0))
        t.assertIdentical(iframeBody, $(iframeBody).get(0))
        t.assertEqual('B', iframeEl.pluck('tagName').join(','))
        t.assertEqual('Hello from iframe!', iframeEl.text())
      },

      testDollarWithFragment: function(t){
        var fragment = $("<div>")
        t.assertLength(1, fragment)
        t.assertEqual("<div></div>", outerHTML(fragment.get(0)))
        t.assertEqual('', fragment.selector)
        t.assertNull(fragment.get(0).parentNode)

        fragment = $("<div>hello world</div>")
        t.assertLength(1, fragment)
        t.assertEqual("<div>hello world</div>", outerHTML(fragment.get(0)))
        t.assertEqual('', fragment.selector)

        fragment = $("<div>hello</div> <span>world</span>")
        t.assertLength(3, fragment)
        t.assertEqual("<div>hello</div>", outerHTML(fragment.get(0)))
        t.assertEqual(Node.TEXT_NODE, fragment.get(1).nodeType)
        t.assertEqual("<span>world</span>", outerHTML(fragment.get(2)))
        t.assertEqual('', fragment.selector)

        fragment = $("<div>\nhello</div> \n<span>world</span>")
        t.assertLength(3, fragment)
        t.assertEqual("<div>\nhello</div>", outerHTML(fragment.get(0)))
        t.assertEqual(Node.TEXT_NODE, fragment.get(1).nodeType)
        t.assertEqual("<span>world</span>", outerHTML(fragment.get(2)))
        t.assertEqual('', fragment.selector)

        fragment = $("<div /><div />")
        t.assertLength(2, fragment)

        fragment = $("<div>hello</div> ")
        t.assertLength(1, fragment)
      },

      testDollarFragmentAndProperties: function(t){
        var el = $('<p id=hi />', {
          id: 'hello', 'class': 'one two',
          text: 'world', css: {color: 'red'}
        })

        t.assertEqual('hello', el.attr('id'))
        t.assert(el.hasClass('one'))
        t.assert(el.hasClass('two'))
        t.assertEqual('world', el.text())
        t.assertEqual('red', el.css('color'))
      },

      testDollarNonemptyFragmentAndProperties: function(t){
        var zepto = $('<a>Goodbye</a>', { text: "Hello", href: "http://zeptojs.com" })
        t.assertLength(1, zepto)
        t.assertEqual('Hello', zepto.text())
        t.assertEqual('http://zeptojs.com', zepto.attr("href"))
      },

      testDollarWithTextNode: function(t){
        var textNode = $(document.createTextNode('hi there'))
        t.assertLength(1, textNode)
        t.assertEqual(Node.TEXT_NODE, textNode.get(0).nodeType)
      },

      testDollarWithCommentInFragment: function(t){
        var comment = $('<!-- -->')
        t.assertLength(1, comment)
        t.assertEqual(Node.COMMENT_NODE, comment.get(0).nodeType)
      },

      testDollarWithDoctypeInFragment: function(t){
        t.assertLength(0, $('<!DOCTYPE html>'))
      },

      testNodeCreationViaDollar: function (t) {
        t.assertEqual('<div></div>', outerHTML($('<div></div>').get(0)))
        t.assertEqual('<div></div>', outerHTML($('<div/>').get(0)))
        t.assertEqual('<div><div></div></div>', outerHTML($('<div><div></div></div>').get(0)))
        t.assertEqual('<div><div></div></div>', outerHTML($('<div><div/></div>').get(0)))
        t.assertEqual('<div><div></div><div></div></div>', outerHTML($('<div><div></div><div></div></div>').get(0)))
      },

      testCreateTableCell: function(t) {
        t.assertEqual('TD', $('<td></td>').pluck('nodeName').join(','))
      },

      testCreateTableHeaderCell: function(t) {
        t.assertEqual('TH', $('<th></th>').pluck('nodeName').join(','))
      },

      testCreateTableRow: function(t) {
        t.assertEqual('TR', $('<tr></tr>').pluck('nodeName').join(','))
      },

      testCreateTableHeader: function(t) {
        t.assertEqual('THEAD', $('<thead></thead>').pluck('nodeName').join(','))
      },

      testCreateTableBody: function(t) {
        t.assertEqual('TBODY', $('<tbody></tbody>').pluck('nodeName').join(','))
      },

      testCreateTableFooter: function(t) {
        t.assertEqual('TFOOT', $('<tfoot></tfoot>').pluck('nodeName').join(','))
      },

      testCreateSelectOptgroup: function(t) {
        t.assertEqual('OPTGROUP', $('<optgroup></optgroup>').pluck('nodeName').join(','))
      },

      testCreateSelectOption: function(t) {
        t.assertEqual('OPTION', $('<option></option>').pluck('nodeName').join(','))
      },

      testReady: function(t){
        t.assertEqual('hi!', globalVarSetFromReady)
        t.assertEqual('hi!', globalVarSetFromReady2)
        t.assertEqual('hi!', globalVarSetFromReady3)
        t.assertEqual('hi!', globalVarSetFromReady4)
      },

      testNext: function(t){
        t.assertEqual('P', $('#some_element').next().get(0).tagName)
        t.assertEqual('DIV', $('p').next().get(0).tagName)

        t.assertEqual(0, $('span.yay').next('.nay').size())
        t.assertEqual(1, $('span.yay').next().size())
        t.assertEqual(1, $('span.yay').next().next('.nay').size())
      },

      testPrev: function(t){
        t.assertEqual('H1', $('p').prev().get(0).tagName)
        t.assertEqual('DIV', $('ul').prev().get(0).tagName)

        t.assertEqual(0, $('span.nay').prev('.yay').size())
        t.assertEqual(1, $('span.nay').prev().size())
        t.assertEqual(1, $('span.nay').prev().prev('.yay').size())
      },

      testEach: function(t){
        var index, tagnames = []
        $('#eachtest > *').each(function(idx, el){
          index = idx
          t.assertIdentical(el, this)
          tagnames.push(el.tagName.toUpperCase())
        })
        t.assertEqual('SPAN, B, BR', tagnames.join(', '))
        t.assertEqual(2, index)
      },

      testEachBreak: function(t){
        var index, tagnames = []
        $('#eachtest > *').each(function(idx, el){
          index = idx
          t.assertIdentical(el, this)
          tagnames.push(el.tagName.toUpperCase())
          if (idx == 1) return false
        })
        t.assertEqual('SPAN, B', tagnames.join(', '))
        t.assertEqual(1, index)
      },

      testMap: function(t){
        var results = $('#eachtest > *').map(function(idx, el) {
          t.assertIdentical(el, this)
          return idx + ':' + this.nodeName.toUpperCase()
        })
        t.assertEqual(3, results.size())
        t.assertEqual('0:SPAN, 1:B, 2:BR', results.get().join(', '))
      },

      testDollarMap: function(t){
        var fruits = ['apples', 'oranges', 'pineapple', 'peach', ['grape', 'melon']]
        var results = $.map(fruits, function(item, i) {
          if (item instanceof Array) return item
          else if (!/apple/.test(item)) return i + ':' + item
        })
        t.assertEqual('1:oranges,3:peach,grape,melon', results.join(','))
      },

      testDollarMapObject: function(t){
        var fruit = { name: 'banana', taste: 'sweet' }
        var results = $.map(fruit, function(value, key) {
          return key + '=' + value
        })
        t.assertEqual('name=banana,taste=sweet', results.sort().join(','))
      },

      testDollarGrep: function(t){
        var fruits = ['apples', 'oranges', 'pineapple', 'peach']
        var result = $.grep(fruits, function(name){ return /apple/.test(name) })
        t.assertEqualCollection(['apples', 'pineapple'], result)
      },

      testDollarEach: function(t){
        var array = ['a','b','c'], object = { a: 1, b: 2, c: 3 }, result

        result = []
        $.each(array, function(idx, val){
          result.push(idx)
          result.push(val)
        })
        t.assertEqual('0a1b2c', result.join(''))

        result = []
        $.each(object, function(key, val){
          result.push(key)
          result.push(val)
        })
        t.assertEqual('a1b2c3', result.join(''))

        result = []
        $.each(array, function(idx, val){
          result.push(idx)
          result.push(val)
          return idx<1
        })
        t.assertEqual('0a1b', result.join(''))

        t.assertEqual('abc', $.each(array, function(){}).join(''))
      },

      testDollarEachContext: function(t){
        $.each(['a'], function(key, val) {
          t.assertEqual(this, val)
        })
        $.each({a:'b'}, function(key, val) {
          t.assertEqual(this, val)
        })
      },

      testDollarInArray: function(t) {
        t.assertIdentical( 0,  $.inArray(1, [1,2,3]) )
        t.assertIdentical( 1,  $.inArray(2, [1,2,3]) )
        t.assertIdentical( -1, $.inArray(4, [1,2,3]) )
        t.assertIdentical( 3,  $.inArray(1, [1,2,3,1], 1) )
      },

      testDollarParseJSON: function(t) {
        t.assertSame({a:'b'}, $.parseJSON('{"a":"b"}'))
      },

      testEq: function(t){
        var $els = $('#eq_test div')
        t.assertLength(1, $els.eq(0))
        t.assertLength(1, $els.eq(-1))
        t.assertEqual($els.eq(-1)[0].className, 'eq2')
        t.assertUndefined($els.eq(-1).tagName)

        t.assertLength(0, $('nonexistent').eq(0))
      },

      testFirst: function(t){
        var zepto = $('h1,p')
        t.assertLength(5, zepto)

        var zepto2 = zepto.first()
        t.refuteIdentical(zepto, zepto2)
        t.assertLength(5, zepto)

        t.assertLength(1, zepto2)
        t.assertEqual('H1', zepto2.get(0).tagName)

        t.assertLength(0, $('nonexistent').first())
      },

      testFirstNonDOM: function(t){
        t.assertEqual('a', $(['a', 'b', 'c']).first())
      },

      testLast: function(t){
        var zepto = $('h1,p')
        t.assertLength(5, zepto)

        var zepto2 = zepto.last()
        t.refuteIdentical(zepto, zepto2)
        t.assertLength(5, zepto)

        t.assertLength(1, zepto2)
        t.assertEqual('P', zepto2.get(0).tagName)

        t.assertLength(0, $('nonexistent').last())
      },

      testLastNonDOM: function(t){
        t.assertEqual('c', $(['a', 'b', 'c']).last())
      },

      testPluck: function(t){
        t.assertEqual('H1DIVDIV', $('h1,div.htmltest').pluck('tagName').join(''))
      },

      testShow: function(t){
        $('#show_hide_div1').show()
        t.assertEqual('inline-block', getComputedStyle($('#show_hide_div1').get(0)).display)

        $('#show_hide_div2').show()
        t.assertEqual('block', getComputedStyle($('#show_hide_div2').get(0)).display)

        $('#show_hide_div3').show()
        t.assertEqual('block', getComputedStyle($('#show_hide_div3').get(0)).display)

        $('#show_hide_span1').show()
        t.assertEqual('block', getComputedStyle($('#show_hide_span1').get(0)).display)

        $('#show_hide_span2').show()
        t.assertEqual('block', getComputedStyle($('#show_hide_span2').get(0)).display)

        $('#show_hide_span3').show()
        t.assertEqual('inline', getComputedStyle($('#show_hide_span3').get(0)).display)
      },

      testHide: function(t){
        $('#show_hide_div1').hide()
        t.assertEqual('none', $('#show_hide_div1').get(0).style.display)

        $('#show_hide_div2').hide()
        t.assertEqual('none', $('#show_hide_div2').get(0).style.display)

        $('#show_hide_div3').hide()
        t.assertEqual('none', $('#show_hide_div3').get(0).style.display)

        $('#show_hide_span1').hide()
        t.assertEqual('none', $('#show_hide_span1').get(0).style.display)

        $('#show_hide_span2').hide()
        t.assertEqual('none', $('#show_hide_span2').get(0).style.display)

        $('#show_hide_span3').hide()
        t.assertEqual('none', $('#show_hide_span3').get(0).style.display)
      },

      testToggle: function(t){
        var el = $('#show_hide_div1').hide(),
            domStyle = el.get(0).style

        t.assertEqual('none', domStyle.display)

        var result = el.toggle()
        t.assertIdentical(el, result, 'expected toggle() to return self')
        t.assertIdentical('', domStyle.display)

        el.toggle()
        t.assertEqual('none', domStyle.display)

        el.toggle(true)
        t.assertIdentical('', domStyle.display)

        el.toggle(true)
        t.assertIdentical('', domStyle.display)

        el.toggle(false)
        t.assertEqual('none', domStyle.display)

        el.toggle(false)
        t.assertEqual('none', domStyle.display)
      },

      testToggleMultiple: function(t){
        var el1  = $('#show_hide_div1').hide(),
            el2  = $('#show_hide_div2').show(),
            both = $('#show_hide_div1, #show_hide_div2')

        both.toggle()
        t.assertIdentical('', el1.get(0).style.display)
        t.assertEqual('none', el2.get(0).style.display)

        both.toggle()
        t.assertEqual('none', el1.get(0).style.display)
        t.assertEqual('block', el2.get(0).style.display)
      },

      testOffset: function(t){
        // TODO
        t.assertNull($('#doesnotexist').offset())
        var el = $('#some_element')
        t.assertIdentical(el, el.offset({}))
      },

      testWidth: function(t){
        t.assertNull($('#doesnotexist').width())
        // can't check values here, but make sure it doesn't error out
        var viewportWidth = $(window).width()
        t.assert(viewportWidth > 0 || viewportWidth === 0)
        t.assert($(document).width())

        t.assertIdentical(100, $('#offset').width())
        $('#offset').width('90px')
        t.assertIdentical(90, $('#offset').width())
        $('#offset').width(110)
        t.assertIdentical(110, $('#offset').width())
        $('#offset').width(function(i, oldWidth) { return oldWidth + 5 })
        t.assertIdentical(115, $('#offset').width())
      },

      testHeight: function(t){
        t.assertNull($('#doesnotexist').height())
        // can't check values here, but make sure it doesn't error out
        var viewportHeight = $(window).height()
        t.assert(viewportHeight > 0 || viewportHeight === 0)
        t.assert($(document).height())

        // with a tall element on the page,
        // the window (viewport) should be shorter than the total
        // document height
        $('<div style="height:9999px" id="very_high"></div>').appendTo('body')
        t.assert(
          $(window).height() < $(document).height(),
          "'window' height was not smaller than 'document' height?")
        $('#very_high').remove()

        t.assertIdentical(50, $('#offset').height())
        $('#offset').height('60px')
        t.assertIdentical(60, $('#offset').height())
        $('#offset').height(70)
        t.assertIdentical(70, $('#offset').height())
        $('#offset').height(function(i, oldHeight) { return oldHeight + 5 })
        t.assertIdentical(75, $('#offset').height())
      },

      testClosest: function(t){
        var el = $('#li2')
        t.assertEqualCollection(el, el.closest('li'))
        t.assertEqualCollection($('#nested'), el.closest('ul'))
        // with context
        t.assertEqualCollection($('#nested'), el.closest('ul', $('#li1').get(0)))
        t.assertLength(0, el.closest('#parents', $('#li1').get(0)))
        // no ancestor matched
        t.assertLength(0, el.closest('form'))
      },

      testClosestWithCollection: function(t){
        var targets = $('#parents > li')
        var result = $('#li2').closest(targets)
        t.assertLength(1, result)
        t.assertEqual('li1', result.get(0).id)

        t.assertLength(0, $('#li1').closest('#li2'))
      },

      testClosestWithElement: function(t){
        var target = $('#li1').get(0)
        var result = $('#li2').closest(target)
        t.assertLength(1, result)
        t.assertIdentical(target, result.get(0))

        t.assertLength(0, $('#li1').closest($('#li2').get(0)))
      },

      testClosestOnDetached: function(t){
        var el = $('<div><p><a></a></p></div>'),
            para = el.children(),
            link = para.children()

        t.assertEqualCollection(para, link.closest('p'))
        t.assertEqualCollection(el, link.closest('div'))
        t.assertEqualCollection(el, el.closest('div'))
      },

      testContains: function(t){
        var el1 = $('#li1'), el2 = $('#li2')

        t.assertTrue($.contains(el1.get(0), el2.get(0)))
        t.assertFalse($.contains(el1.get(0), $('#parents').get(0)))
      },

      testContainsOnDetached: function(t){
        var el = $('<div><p><a></a></p></div>'),
            para = el.children(),
            link = para.children()

        t.assertTrue($.contains(para.get(0), link.get(0)))
        t.assertFalse($.contains(document.body, el.get(0)))
      },

      testParents: function(t){
        var body = document.body, html = body.parentNode, container = $('#parents'),
          wrapper = $('#fixtures').get(0)
        t.assertEqualCollection($([wrapper, body, html]), container.parents())

        var expected = $('#li1 > ul').get()
        expected.push($('#li1').get(0))
        expected.push(container.get(0))
        expected = expected.concat([wrapper, body, html])
        t.assertEqualCollection($(expected), $('#li1').find('li').parents())

        expected = [$('#nested').get(0), $('#parents').get(0)]
        t.assertEqualCollection($(expected), $('#li2').parents('ul'))
      },

      testParentsIframe: function(t){
        var iframeBody = $('iframe').get(0).contentDocument.body
        t.assertEqualCollection(
          [iframeBody, iframeBody.parentNode],
          $(iframeBody).find('b').first().parents()
        )
      },

      testParent: function(t){
        var el = $('#li1')
        t.assertEqualCollection($('#parents'), el.parent())
        t.assertEqualCollection($('#li1 > ul'), el.find('li').parent())
        t.assertLength(0, $(document.createElement('div')).parent())
      },

      testParentOnDetached: function(t){
        t.assertLength(0, $('<ul />').parent())
      },

      testChildren: function(t){
        var el=$("#childrenTest"), lis=$("li.child",el)

        //basic form
        t.assertEqualCollection(lis, el.children())
        //filtered by selector
        t.assertEqualCollection(lis.filter(".two"), el.children(".two"))
        //children == null
        t.assertLength(4,lis.children(null))
        //across multiple parents
        t.assertEqualCollection(el.find("li a"), lis.children("a"))
        //chainabilty
        t.assertEqual(el.find("li a.childOfTwo").text(), lis.children(".childOfTwo").text())
        //non-existent children
        t.assertLength(0,lis.children(".childOfTwo").children())
      },

      testContents: function(t){
        var $contents = $("#contentsTest").contents()
        t.assertLength(3, $contents)
        t.assertLength(2, $contents.filter('span'))
        t.assertLength(0, $("#contentsEmptyTest").contents())
      },

      testSiblings: function(t){
        var el=$("#siblingsTest")

        //basic form
        t.assertEqualCollection($("li.one,li.three,li.four",el), $("li.two",el).siblings())
        //filtered by selector
        t.assertEqualCollection($("li.three",el), $("li.two",el).siblings(".three"))
        //across multiple parents
        t.assertEqualCollection(el.find("li b"), $("li em",el).siblings("b"))
        t.assertLength(6,$("li span",el).siblings())
        //non-existent siblings
        t.assertLength(0,$("li span.e",el).siblings())
      },

      testNot: function(t){
        var el=$("#notTest")

        //selector form
        t.assertEqualCollection($("li.one,li.three,li.four",el), $("li",el).not(".two"))
        //element or NodeList form
        t.assertEqualCollection($("span.b,span.c,span.e",el), $("span",el).not(document.getElementById("notTestExclude")))
        t.assertEqualCollection($("li",el), $("li, span",el).not(document.getElementsByTagName("span")))
        //function form
        t.assertEqualCollection($("span.b,span.c",el),$("span",el).not(function(i){
          var $this=$(this)
          $this.html(i)
          return ($this.hasClass("d") || $this.hasClass("e")) ? true : false
        }))
        //test the index was passed in properly in previous test
        t.assertEqual("0",$("span.b",el).text())
        t.assertEqual("1",$("span.c",el).text())
      },

      testReplaceWith: function(t) {
        $('div.first').replaceWith('<h2 id="replace_test">New heading</h2>')
        t.assertUndefined($('div.first').get(0))
        t.assert(document.getElementById("replace_test").nodeType)
        t.assertEqual($('.replacewith h2#replace_test').get(0), document.getElementById("replace_test"))

        $('#replace_test').replaceWith($('.replace_test_div'))
        t.assertUndefined($('#replace_test').get(0))
        t.assert(document.getElementsByClassName("replace_test_div")[0].nodeType)
        t.assertEqual($('.replacewith h2#replace_test').get(0), document.getElementsByClassName("replace_test")[0])

        //Multiple elements
        $('.replacewith .replace_test_div').replaceWith('<div class="inner first">hi</div><div class="inner fourth">hello</div>')
        t.assertLength(4,$('.replacewith div'))
        t.assertEqual("inner first", $('.replacewith div')[0].className)
        t.assertEqual("inner fourth", $('.replacewith div')[1].className)
      },

      testReplaceWithFragment: function(t) {
        var orphanDiv = $("<div />")
        orphanDiv.replaceWith($("<div class='different' />"))
        t.assert(!orphanDiv.hasClass('different'))
      },

      testWrap: function(t) {
        var el = $('#wrap_test')
        el.find('span').wrap('<p><i/></p>')
        t.assertEqual(
          '<p><i><span>hi</span></i></p><a></a><p><i><span>hello</span></i></p>',
          el.html()
        )

        // avoids unnecessary cloning of dom structure for wrapping
        el = $('<div><a/></div>')
        var structure = $('<span/>')
        el.find('a').wrap(structure)
        t.assertIdentical(structure.get(0), el.find('span').get(0))
        t.assert(el.find('a').parent().is('span'))
      },

      testWrapFunction: function(t) {
        var el = $('<div><b>A</b><b>B</b></div>')
        el.find('b').wrap(function(index){
          return '<a class=link' + index + $(this).text() + ' />'
        })
        t.assertEqual(
          '<a class="link0A"><b>A</b></a><a class="link1B"><b>B</b></a>',
          el.html()
        )
      },

      testWrapAll: function(t) {
        var el = $('#wrapall_test')
        el.find('span').wrapAll('<p><a/></p>')
        t.assertEqual(
          '<b></b><p><a><span>hi</span><span>hello</span></a></p><i></i>',
          el.html()
        )
      },

      testWrapFragment: function(t) {
        var fragment = $('<div id="fragment" />')
        fragment.wrapAll('<div id="wrap_test" />')
        t.assertEqual('wrap_test', fragment.parent().attr('id'))
        t.assertEqual(0, fragment.children().length)

        fragment = $('<div id="fragment" />')
        fragment.wrap('<div id="wrap_test" />')
        t.assertEqual('wrap_test', fragment.parent().attr('id'))
        t.assertEqual(0, fragment.children().length)
      },

      testWrapInner: function(t) {
        var $el = $('#wrapinner_test')
        $el.wrapInner('<div>')
        t.assertLength(1, $el.children())
        t.assertLength(1, $el.children('div'))
        t.assertLength(3, $el.find('div').contents())

        $el = $('#wrapinner_empty_test')
        $el.wrapInner('<div>')
        t.assertLength(1, $el.children())
        t.assertLength(1, $el.children('div'))
        t.assertLength(0, $el.find('div').contents())
      },

      testWrapInnerFunction: function(t) {
        var el = $('<div><b>A</b><b>B</b></div>')
        el.find('b').wrapInner(function(index){
          return '<a class=link' + index + $(this).text() + ' />'
        })
        t.assertEqual(
          '<b><a class="link0A">A</a></b><b><a class="link1B">B</a></b>',
          el.html()
        )
      },

      testUnwrap: function(t){
        var context=$("#unwrap_test")

        //Element With no siblings
        $(".unwrap_one span",context).unwrap()
        t.assertLength(1,$("b",context))

        //Element with siblings
        $(".unwrap_two span",context).unwrap()
        t.assertLength(0,$("b",context))
        //make sure siblings are unaffected
        t.assertLength(3,$("span",context))
        //make sure parents are what they should be
        t.assertEqual($("span",context).parent().get(0), document.getElementsByClassName("unwrap_one")[0])
      },

      testUnwrapFragment: function(t){
        var fragment = $('<div id=outer><div id=inner></div><div id=uninvolved></div></div>'),
            innerFragment = fragment.find("#inner"),
            uninvolved = fragment.find("#uninvolved")

        innerFragment.unwrap()
        t.assertLength(0, innerFragment.parent(), '#inner should be orphan')
        t.assertLength(0, uninvolved.parent(),    '#uninvolved should be orphan')
        t.assertLength(0, fragment.children(),    'fragment should be empty')
      },

      testClone: function(t){
        var el = $('<div class=sheep><span></span></div>'),
            el2 = el.clone()

        t.assert(el2.hasClass('sheep'))
        el2.addClass('black')
        t.refute(el.hasClass('black'))

        el2.find('span').text('baa')
        t.assertIdentical('', el.find('span').text())
      },

      testFind: function(t){
        var found = $('p#find1').find('span.findme')
        t.assertLength(4, found)
        t.assertEqual('1', found.get(0).innerHTML)
        t.assertEqual('2', found.get(1).innerHTML)
        t.assertEqual('4', found.get(2).innerHTML)
        t.assertEqual('5<span>6</span>', found.get(3).innerHTML)

        var found = $('p#find1, #find2').find('span')
        t.assertLength(11, found)
      },

      testFindWithCollection: function(t){
        var targets = $('#find1 span span, #find1 b, #find2 span')
        var found = $('p#find1').find(targets)
        t.assertLength(2, found)
        t.assertEqual('B', found.get(0).tagName)
        t.assertEqual('6', found.get(1).innerHTML)
      },

      testFindWithElement: function(t){
        var target = $('#find1 span span').get(0)
        var found = $('p#find1').find(target)
        t.assertLength(1, found)
        t.assertEqual('6', found.get(0).innerHTML)

        found = $('p#find1').find(document.body)
        t.assertLength(0, found, "no elements should have matched")
      },

      testFindWithInvalidNode: function(t) {
        var found = $('<div><a>1</a></div>\n<div></div>').find('a')
        t.assertLength(1, found)
        t.assertEqual('1', found.get(0).innerHTML)
      },

      testFilter: function(t){
        var found = $('div')
        t.assertLength(2, found.filter('.filtertest'))
        t.assertLength(0, found.filter('.doesnotexist'))
        t.assertLength(1, found.filter('.filtertest').filter(':nth-child(2n)'))

        var nodes = $('<select><option value=1>test1</option><option value=2>test2</option><option value=1>test1</option></select>')
        t.assertLength(2, nodes.find('option').filter(function(){ return this.value == '1' }))

        var indexes = []
        nodes.find('option').filter(function(index){ if (this.value=='1') indexes.push(index) })
        t.assertEqualCollection([0,2], indexes)
      },

      testFilterWithNonNativeArrayFilter: function(t){
        var nativeFilter = Array.prototype.filter
        try {
          // apply broken filter
          Array.prototype.filter = function(){ return [] }
          t.assertLength(2, $('div').filter('.filtertest'))
        } finally {
          Array.prototype.filter = nativeFilter
        }
      },

      testHas: function(t){
        var result, el = $('<b id=one><a></a></b><b id=two><i></i></b><b id=three><i></i></b>')
        result = el.has('a')
        t.assertEqual('one', result.pluck('id').join(' '))
        result = el.has('i')
        t.assertEqual('two three', result.pluck('id').join(' '))
        result = el.has(el.find('i').get(0))
        t.assertEqual('two', result.pluck('id').join(' '))
      },

      testAdd: function(t){
        var lis=$("li"),spans=$("span"),
        together=lis.add("span"),
        duplicates=spans.add("span"),
        disconnected=$("<div></div>").add("<span></span>"),
        mainContext=$("#addTest")

        //uniquness of collection
        t.assertLength(spans.length, duplicates)

        //selector only
        t.assertLength((lis.length + spans.length), together)

        //selector with context
        t.assertEqualCollection($("span",mainContext), $(".add_span").add(".add_span_exclude",mainContext))

        //DOM Element + Chaining test
        t.assertEqualCollection(mainContext.children(), $(".add_span").add(".add_span_exclude").add(document.getElementById("addTestDiv")))

        //Disconnected
        t.assert(!disconnected.get(0).parentNode)

        $("#addTestDiv").append(disconnected)
        t.assertEqual('<div></div><span></span>', document.getElementById("addTestDiv").innerHTML)
      },

      testIs: function(t){
        t.assert($('#find1').is('p'))
        t.assert($('#li2').is(':first-child'))
        t.assert(!$('#find1').is('doesnotexist'))
        t.assert(!$('#find1').is())

        t.assert($('#fixtures div').is('#some_element'))
        t.assert(!$('#doesnotexist').is('p'))

        t.assert(!$(window).is('p'))
      },

      testIsWithoutParent: function(t){
        var elem = $('<div id=outOfDOM />')
        t.assert(elem.is('div'))
        t.assert(elem.is('#outOfDOM'))
        t.assert(!elem.is('p'))
        t.assert(!elem.is())
      },

      testCSS: function(t){
        var el = $('#some_element').get(0)

        // single assignments
        $('#some_element').css('color', '#f00')
        $('#some_element').css('margin-top', '10px')
        $('#some_element').css('marginBottom', '5px')
        $('#some_element').css('left', 42)
        $('#some_element').css('z-index', 10)
        $('#some_element').css('fontWeight', 300)
        $('#some_element').css('border', '1px solid rgba(255,0,0,0)')
        t.assertEqual('rgb(255, 0, 0)', el.style.color)
        t.assertEqual('rgba(255, 0, 0, 0)', el.style.borderLeftColor)
        t.assertEqual('1px', el.style.borderLeftWidth)
        t.assertEqual('10px', el.style.marginTop)
        t.assertEqual('5px', el.style.marginBottom)
        t.assertEqual('42px', el.style.left)
        t.assertEqual(300, el.style.fontWeight)
        t.assertEqual(10, el.style.zIndex)

        // read single values, including shorthands
        t.assertEqual('rgb(255, 0, 0)',
          $('#some_element').css('color'))
        t.assertEqual('1px solid rgba(255, 0, 0, 0)',
          $('#some_element').css('border'))

        // multiple assignments
        $('#some_element').css({
          'border': '2px solid #000',
          'color': 'rgb(0,255,0)',
          'padding-left': '2px'
        })
        t.assertEqual('2px', $('#some_element').css('borderLeftWidth'))
        t.assertEqual('solid', $('#some_element').css('borderLeftStyle'))
        t.assertEqual('rgb(0, 0, 0)', $('#some_element').css('borderLeftColor'))
        t.assertEqual('rgb(0, 255, 0)', $('#some_element').css('color'))
        t.assertEqual('2px', $('#some_element').css('paddingLeft'))
        t.assertEqual('2px', $('#some_element').css('border-left-width'))
        t.assertEqual('solid', $('#some_element').css('border-left-style'))
        t.assertEqual('rgb(0, 0, 0)', $('#some_element').css('border-left-color'))
        t.assertEqual('rgb(0, 255, 0)', $('#some_element').css('color'))
        t.assertEqual('2px', $('#some_element').css('padding-left'))

        // read multiple values, camelCased CSS
        var arrCamelCss = $('#some_element').css(['borderLeftWidth', 'borderLeftStyle', 'borderLeftColor', 'color'])
        t.assertEqual('2px', arrCamelCss['borderLeftWidth'])
        t.assertEqual('solid', arrCamelCss['borderLeftStyle'])
        t.assertEqual('rgb(0, 0, 0)', arrCamelCss['borderLeftColor'])
        t.assertEqual('rgb(0, 255, 0)', arrCamelCss['color'])
        t.assertUndefined(arrCamelCss['paddingLeft'])

        // read multiple values, dashed CSS property names
        var arrDashedCss = $('#some_element').css(['border-left-width', 'border-left-style', 'border-left-color', 'color'])
        t.assertEqual('2px', arrDashedCss['border-left-width'])
        t.assertEqual('solid', arrDashedCss['border-left-style'])
        t.assertEqual('rgb(0, 0, 0)', arrDashedCss['border-left-color'])
        t.assertEqual('rgb(0, 255, 0)', arrDashedCss['color'])
        t.assertUndefined(arrDashedCss['padding-left'])

        // make sure reads from empty Zepto collections just return undefined
        t.assertUndefined($().css(['border-left-width']))

        var div = $('#get_style_element')
        t.assertEqual('48px', div.css('font-size'))
        t.assertEqual('rgb(0, 0, 0)', div.css('color'))
      },

      testCSSUnset: function (t) {
        var el = $('#some_element').css({ 'margin-top': '1px', 'margin-bottom': '1px' }),
            dom = el.get(0)

        el.css('color', '#000')
        el.css('color', '')
        t.assertIdentical('', dom.style.color)

        el.css('color', '#000')
        el.css('color', undefined)
        t.assertIdentical('', dom.style.color)

        el.css('color', '#000')
        el.css('color', null)
        t.assertIdentical('', dom.style.color)

        el.css('color', '#000')
        el.css({ color: '', 'margin-top': undefined, 'marginBottom': null })
        t.assertIdentical('', dom.style.color)
        t.assertIdentical('', dom.style.marginTop)
        t.assertIdentical('', dom.style.marginBottom)
      },

      testCSSZeroValue: function (t) {
        var el = $('#some_element'), dom = el.get(0)
        el.css('opacity', 0)
        t.assertIdentical('0', dom.style.opacity)

        el.css('opacity', 1)
        el.css({ opacity: 0 })
        t.assertIdentical('0', dom.style.opacity)
      },

      testCSSOnNonExistingElement: function (t) {
        var errorWasRaised = false
        try {
          var color = $('.some-non-exist-elm').css('color')
        } catch (e) {
          errorWasRaised = true
        }
        t.assert(!errorWasRaised)
      },

      testHtml: function(t){
        var div = $('div.htmltest');

        div.text(undefined);
        t.assertEqual('', div.html());

        t.assertIdentical(div, div.html('yowza'))
        t.assertEqual('yowza', document.getElementById('htmltest1').innerHTML)
        t.assertEqual('yowza', document.getElementById('htmltest2').innerHTML)

        t.assertEqual('yowza', $('div.htmltest').html())

        div.html('')
        t.assertEqual('', document.getElementById('htmltest2').innerHTML)

        t.assertEqual("", $('#htmltest3').html())

        t.assertNull($('doesnotexist').html())

        div.html('yowza')
        div.html(function(idx, html){
          return html.toUpperCase()
        })
        t.assertEqual('YOWZA', div.html())

        div.html('<u>a</u><u>b</u><u>c</u>')

        $('u').html(function(idx,html){
          return idx+html
        })
        t.assertEqual('<u>0a</u><u>1b</u><u>2c</u>', div.html())

        var table = $('#htmltest4'),
          html = '<tbody><tr><td>ok</td></tr></tbody>'
        table.html('<tbody><tr><td>ok</td></tr></tbody>')
        t.assertEqual(html, table.html())
      },

      testText: function(t){
        // test basics with Zepto-created DOM elements
        t.assertEqual('',         $('<h1/>').text())
        t.assertEqual('',         $('<h1/>').text('').text())
        t.assertEqual('',         $('<h1/>').text(undefined).text())
        t.assertEqual('null',     $('<h1/>').text(null).text())
        t.assertEqual('1',        $('<h1/>').text(1).text())
        t.assertEqual('<b>a</b>', $('<h1/>').text('<b>a</b>').text())

        t.assertEqual('&lt;b&gt;a&lt;/b&gt;',
          $('<h1/>').text('<b>a</b>').html())

        // now test with some existing DOM elements
        $('#texttest3').text(undefined)
        t.assertEqual('', $('#texttest3').text())

        t.assertEqual('Here is some text', $('div.texttest').text())
        t.assertEqual('And some more', $('#texttest2').text())

        $('div.texttest').text("Let's set it")
        t.assertEqual("Let's set it", $('#texttest1').text())
        t.assertEqual("Let's set it", $('#texttest2').text())

        $('#texttest2').text('')
        t.assertEqual("Let's set it", $('div.texttest').text())
        t.assertEqual('', $('#texttest2').text())
      },

      testEmpty: function(t) {
        $('#empty_test').empty()

        t.assertEqual(document.getElementById('empty_1'), null)
        t.assertEqual(document.getElementById('empty_2'), null)
        t.assertEqual(document.getElementById('empty_3'), null)
        t.assertEqual(document.getElementById('empty_4'), null)
      },

      testAttr: function(t){
        var els = $('#attr_1, #attr_2')

        t.assertEqual('someId1', els.attr("data-id"))
        t.assertEqual('someName1', els.attr("data-name"))

        els.attr("data-id","someOtherId")
        els.attr("data-name","someOtherName")

        t.assertEqual('someOtherId', els.attr("data-id"))
        t.assertEqual('someOtherName', els.attr("data-name"))
        t.assertEqual('someOtherId', $('#attr_2').attr('data-id'))

        t.assertNull(els.attr("nonExistentAttribute"))

        els.attr("data-id", false)
        t.assertEqual("false", els.attr("data-id"))

        els.attr("data-id", 0)
        t.assertEqual("0", els.attr("data-id"))

        els.attr({ 'data-id': 'id', 'data-name': 'name' })
        t.assertEqual('id', els.attr("data-id"))
        t.assertEqual('name', els.attr("data-name"))
        t.assertEqual('id', $('#attr_2').attr('data-id'))

        els.attr('data-id', function(idx,oldvalue){
          return idx+oldvalue
        })
        t.assertEqual('0id', els.attr('data-id'))
        t.assertEqual('1id', $('#attr_2').attr('data-id'))
      },

      testProp: function(t){
        var label = $('#prop_test1')
        var input = $('#prop_test2')
        var table = $('#prop_test3')
        var td1 = $('#prop_test4')
        var td2 = $('#prop_test5')
        var img = $('#prop_test6')
        var div = $('#prop_test7')

        t.assertEqual(input.prop('tabindex'), -1)
        t.assertEqual(input.prop('readonly'), true)
        t.assertEqual(label.prop('for'), 'prop_test2')
        t.assertEqual(input.prop('class'), 'propTest')
        t.assertEqual(input.prop('maxlength'), 10)
        t.assertEqual(table.prop('cellspacing'), 10)
        t.assertEqual(table.prop('cellpadding'), 5)
        t.assertEqual(td1.prop('rowspan'), 2)
        t.assertEqual(td2.prop('colspan'), 2)
        t.assertEqual(img.prop('usemap'), '#imgMap')
        t.assertEqual(div.prop('contenteditable'), 'true')
      },

      testAttrNoElement: function(t){
        t.assertUndefined($().attr('yo'))
        t.assertUndefined($(document.createTextNode('')).attr('yo'))
        t.assertUndefined($(document.createComment('')).attr('yo'))

        var els = $('<b></b> <i></i>').attr('id', function(i){ return this.nodeName + i })
        t.assertEqual('B0', els.eq(0).attr('id'))
        t.assertEqual('I2', els.eq(2).attr('id'))
        t.assertUndefined(els.eq(1).attr('id'))
      },

      testAttrEmpty: function(t){
        var el = $('#data_attr')
        t.assertIdentical('', el.attr('data-empty'))
      },

      testAttrOnTextInputField: function(t) {
        var inputs, values

        // HTML is set here because IE does not reset
        // values of input fields on page reload
        document.getElementById('attr_with_text_input').innerHTML =
          '<input value="Default input">'+
          '<input type="text" value="Text input">'+
          '<input type="email" value="Email input">'+
          '<input type="search" value="Search input">'

        inputs = $('#attr_with_text_input input')

        values = $.map(inputs, function(i){ return $(i).attr('value') })
        t.assertEqual('Default input, Text input, Email input, Search input', values.join(', '))

        inputs.val(function(i, value){ return value.replace('input', 'changed') })

        values = $.map(inputs, function(i){ return $(i).attr('value') })
        t.assertEqual('Default changed, Text changed, Email changed, Search changed', values.join(', '))
      },

      testAttrNullUnset: function(t){
        var el = $('<div id=hi>')
        el.attr('id', null)
        t.assertIdentical('', el.attr('id'))

        el.attr('id', 'hello')
        el.attr({ id:null })
        t.assertIdentical('', el.attr('id'))
      },

      testRemoveAttr: function(t) {
        var el = $('#attr_remove')
        t.assertEqual('boom', el.attr('data-name'))
        el.removeAttr('data-name')
        t.assertNull(el.attr('data-name'))
      },

      testRemoveAttrNoElement: function(t){
        t.assert($().removeAttr('rel'))
        t.assert($(document.createTextNode('')).removeAttr('rel'))

        var els = $('<b rel=up></b> <i rel=next></i>')
        t.assertIdentical(els, els.removeAttr('rel'))
        t.assertNull(els.eq(0).attr('rel'))
        t.assertUndefined(els.eq(1).attr('rel'))
        t.assertNull(els.eq(2).attr('rel'))
      },

      testData: function(t) {
        var el = $('#data_attr')
        // existing attribute
        t.assertEqual('bar', el.data('foo'))
        t.assertEqual('baz', el.data('foo-bar'))
        t.assertEqual('baz', el.data('fooBar'))

        // camelCase
        el.data('fooBar', 'bam')
        t.assertEqual('bam', el.data('fooBar'))
        t.assertEqual('bam', el.data('foo-bar'))

        // new attribute
        el.data('fun', 'hello')
        t.assertEqual('hello', el.attr('data-fun'))
        t.assertEqual('hello', el.data('fun'))

        // blank values
        t.assertIdentical('', el.data('empty'))
        t.assertUndefined(el.data('does-not-exist'))
      },

      testDataNumberType: function(t){
        var el = $('<div data-num=42 />')
        t.assertIdentical(42, el.data('num'))

        t.assertIdentical("08",
          $('<div data-notnum=08 />').data('notnum'))

        t.assertIdentical(111111111111111111111111111111111,
          $('<div data-bignum="111111111111111111111111111111111" />').data('bignum'))
      },

      testDataBooleanType: function(t){
        var el = $('<div data-true=true data-false=false />')
        t.assertTrue(el.data('true'))
        t.assertFalse(el.data('false'))
      },

      testDataNullType: function(t){
        var el = $('<div data-nil=null />')
        t.assertNull(el.data('nil'))
      },

      testDataJsonType: function(t){
        var el = $('<div data-json=\'["one", "two"]\' data-invalid=\'[boom]\' />')
        var json = el.data('json')
        t.assertEqual(2, json.length)
        t.assertEqual("one", json[0])
        t.assertEqual("two", json[1])
        t.assertEqual('[boom]', el.data('invalid'))
      },

      testVal: function(t) {
        var input = $('#attr_val')

        // some browsers like IE don't reset input values on reload
        // which messes up repeated test runs, so set the start value
        // directly via the DOM API
        document.getElementById('attr_val').value = 'Hello World'

        t.assertEqual('Hello World', input.val())

        input.val(undefined);
        t.assertEqual('undefined', input.val());

        input.val('')
        t.assertEqual('', input.val())

        input.get(0).value = 'Hello again'
        t.assertEqual('Hello again', input.val())

        input.val(function(i, val){ return val.replace('Hello', 'Bye') })
        t.assertEqual('Bye again', input.val())

        t.assertUndefined($('non-existent').val())

        var multiple =
          $('<select multiple><option selected>1</option><option value=2 selected="selected">a</option><option>3</option></select>')
        t.assertEqualCollection(['1','2'], multiple.val())

        // FIXME
        // This is the "approved" way of de-selecting an option
        // Unfortunately, this fails on Chrome 29 for Android
        multiple.find('option')[0].selected = false

        t.assertEqualCollection(['2'], multiple.val(),
          "Expected val() to reflect changes to selected options in a <select multiple> element")
      },

      testChaining: function(t){
        t.assert(document.getElementById('nay').innerHTML == "nay")
        $('span.nay').css('color', 'red').html('test')
        t.assert(document.getElementById('nay').innerHTML == "test")
      },

      testCachingForLater: function(t){
        var one = $('div')
        var two = $('span')

        t.assert(one.get(0) !== two.get(0))
      },

      testPlugins: function(t){
        var el = $('#some_element').get(0)

        $.fn.plugin = function(){
          return this.each(function(){ this.innerHTML = 'plugin!' })
        }
        $('#some_element').plugin()
        t.assertEqual('plugin!', el.innerHTML)

        // test if existing Zepto objects receive new plugins
        if ('__proto__' in {}) {
          var $some_element = $('#some_element')
          $.fn.anotherplugin = function(){
            return this.each(function(){ this.innerHTML = 'anotherplugin!' })
          }
          t.assert(typeof $some_element.anotherplugin == 'function')
          $some_element.anotherplugin()
          t.assertEqual('anotherplugin!', el.innerHTML)
        } else
          window.console && console.warn &&
          console.warn("Browser doesn't support __proto__, skipping test of live extension of existing Zepto objects with plugins")
      },

      testAppendPrependBeforeAfter: function(t){
        $('#beforeafter').append('append')
        $('#beforeafter').prepend('prepend')
        $('#beforeafter').before('before')
        $('#beforeafter').after('after')

        t.assertEqual('before<div id="beforeafter">prependappend</div>after', $('#beforeafter_container').html())

        //testing with TextNode as parameter
        $('#beforeafter_container').html('<div id="beforeafter"></div>')

        function text(contents){
          return document.createTextNode(contents)
        }

        $('#beforeafter').append(text('append'))
        $('#beforeafter').prepend(text('prepend'))
        $('#beforeafter').before(text('before'))
        $('#beforeafter').after(text('after'))

        t.assertEqual('before<div id="beforeafter">prependappend</div>after', $('#beforeafter_container').html())

        $('#beforeafter_container').html('<div id="beforeafter"></div>')

        function div(contents){
          var el = document.createElement('div')
          el.innerHTML = contents
          return el
        }

        $('#beforeafter').append(div('append'))
        $('#beforeafter').prepend(div('prepend'))
        $('#beforeafter').before(div('before'))
        $('#beforeafter').after(div('after'))

        t.assertEqual(
          '<div>before</div><div id="beforeafter"><div>prepend</div>'+
          '<div>append</div></div><div>after</div>',
          $('#beforeafter_container').html()
        )

        //testing with Zepto object as parameter
        $('#beforeafter_container').html('<div id="beforeafter"></div>')

        $('#beforeafter').append($(div('append')))
        $('#beforeafter').prepend($(div('prepend')))
        $('#beforeafter').before($(div('before')))
        $('#beforeafter').after($(div('after')))

        t.assertEqual(
          '<div>before</div><div id="beforeafter"><div>prepend</div>'+
          '<div>append</div></div><div>after</div>',
          $('#beforeafter_container').html()
        )

        //testing with a zepto object of more than one element as parameter
        $(document.body).append('<div class="append">append1</div><div class="append">append2</div>')
        $(document.body).append('<div class="prepend">prepend1</div><div class="prepend">prepend2</div>')
        $(document.body).append('<div class="before">before1</div><div class="before">before2</div>')
        $(document.body).append('<div class="after">after1</div><div class="after">after2</div>')

        $('#beforeafter_container').html('<div id="beforeafter"></div>')

        $('#beforeafter').append($('.append'))
        $('#beforeafter').prepend($('.prepend'))
        $('#beforeafter').before($('.before'))
        $('#beforeafter').after($('.after'))

        t.assertEqual(
          '<div class="before">before1</div><div class="before">before2</div><div id="beforeafter"><div class="prepend">prepend1</div><div class="prepend">prepend2</div>'+
          '<div class="append">append1</div><div class="append">append2</div></div><div class="after">after1</div><div class="after">after2</div>',
          $('#beforeafter_container').html()
        )

        //

        var helloWorlds = [], appendContainer1 = $('<div> <div>Hello</div> <div>Hello</div> </div>'),
            helloDivs = appendContainer1.find('div')

        helloDivs.append(' world!')
        helloDivs.each(function() { helloWorlds.push($(this).text()) })
        t.assertEqual('Hello world!,Hello world!', helloWorlds.join(','))

        //

        var spans = [], appendContainer2 = $('<div> <div></div> <div></div> </div>'),
            appendDivs = appendContainer2.find('div')

        appendDivs.append($('<span>Test</span>'))
        appendDivs.each(function() { spans.push($(this).html()) })
        t.assertEqual('<span>Test</span>,<span>Test</span>', spans.join(','))
      },

      testAppendNull: function(t){
        var el = $(document.body)
        t.assertIdentical(el, el.append(null))
      },

      testBeforeAfterFragment: function(t){
        var fragment = $('<div class=fragment />')
        fragment.before('before').after('after')
        t.assertLength(1, fragment)
        t.assert(fragment.hasClass('fragment'))
      },

      testAppendMultipleArguments: function(t){
        var el = $('<div><span>original</span></div>')
        el.append(
          $('<b>one</b>').get(0),
          $('<b>two</b><b>three</b>').get(),
          $('<b>four</b><b>five</b>'),
          '<b>six</b>'
        )
        t.assertEqual('original one two three four five six',
          $.map(el.children(), function(c){ return $(c).text() }).join(' '))
      },

      testAppendToPrependTo: function(t){
        // testing with Zepto object
        function div(contents){
          var el = document.createElement('div')
          el.innerHTML = contents
          return el
        }

        var ap = $(div('appendto'))
        var pr = $(div('prependto'))

        var ap2 = ap.appendTo($('#appendtoprependto'))
        var pr2 = pr.prependTo($('#appendtoprependto'))

        // the object returned is the correct one for method chaining
        t.assertSame(ap, ap2)
        t.assertSame(pr, pr2)

        t.assertEqual(
          '<div id="appendtoprependto"><div>prependto</div>'+
          '<div>appendto</div></div>',
          $('#appendtoprependto_container').html()
        )

        // zepto object with more than one element
        $(document.body).append('<div class="appendto">appendto1</div><div class="appendto">appendto2</div>')
        $(document.body).append('<div class="prependto">prependto1</div><div class="prependto">prependto2</div>')

        // selector

        // Note that on IE resetting the parent element to be empty will
        // cause inserted elements to be emptied out, so we have to re-create
        // them. This is the same behavior as on jQuery.
        // (Other browsers don't exhibit this problem.)
        ap = $(div('appendto'))
        pr = $(div('prependto'))

        $('#appendtoprependto_container').html('<div id="appendtoprependto"></div>')
        ap.appendTo('#appendtoprependto')
        pr.prependTo('#appendtoprependto')
        t.assertEqual(
          '<div id="appendtoprependto"><div>prependto</div>'+
          '<div>appendto</div></div>',
          $('#appendtoprependto_container').html()
        )

        // reset test elements
        ap = $(div('appendto'))
        pr = $(div('prependto'))
        $('#appendtoprependto_container').html('<div id="appendtoprependto"></div>')
        $('.appendto').appendTo($('#appendtoprependto'))
        $('.prependto').prependTo($('#appendtoprependto'))

        t.assertEqual(
          '<div id="appendtoprependto"><div class="prependto">prependto1</div><div class="prependto">prependto2</div><div class="appendto">appendto1</div><div class="appendto">appendto2</div></div>',
          $('#appendtoprependto_container').html()
        )
      },

      testInsertBeforeInsertAfter: function(t){
        // testing with Zepto object
        function div(contents){
          var el = document.createElement('div')
          el.innerHTML = contents
          return el
        }

        var ib = $(div('insertbefore'))
        var ia = $(div('insertafter'))

        var ibia = $('#insertbeforeinsertafter')
        var ib2 = ib.insertBefore(ibia)
        var ia2 = ia.insertAfter(ibia)

        // test the object returned is correct for method chaining
        t.assertEqual(
          '<div>insertbefore</div><div id="insertbeforeinsertafter">'+
          '</div><div>insertafter</div>',
          $('#insertbeforeinsertafter_container').html()
        )

        // testing with a zepto object of more than one element as parameter
        $(document.body).append('<div class="insertbefore">insertbefore1</div><div class="insertbefore">insertbefore2</div>')
        $(document.body).append('<div class="insertafter">insertafter1</div><div class="insertafter">insertafter2</div>')

        $('#insertbeforeinsertafter_container').html('<div id="insertbeforeinsertafter"></div>')

        $('.insertbefore').insertBefore($('#insertbeforeinsertafter'))
        $('.insertafter').insertAfter($('#insertbeforeinsertafter'))

        t.assertEqual(
          '<div class="insertbefore">insertbefore1</div><div class="insertbefore">insertbefore2</div>'+
          '<div id="insertbeforeinsertafter"></div><div class="insertafter">insertafter1</div>'+
          '<div class="insertafter">insertafter2</div>',
          $('#insertbeforeinsertafter_container').html()
        )

        // testing with a selector as parameter
        $('#insertbeforeinsertafter_container').html('<div id="insertbeforeinsertafter"></div>')

        // reset test elements
        ib = $(div('insertbefore'))
        ia = $(div('insertafter'))
        ib.insertBefore('#insertbeforeinsertafter')
        ia.insertAfter('#insertbeforeinsertafter')

        t.assertEqual(
          '<div>insertbefore</div><div id="insertbeforeinsertafter">'+
          '</div><div>insertafter</div>',
          $('#insertbeforeinsertafter_container').html()
        )
      },

      testAppendEval: function (t) {
        window.someGlobalVariable = 0
        try {
          $('#fixtures').append(
            '<div><b id="newByAppend">Hi</b>' +
            '<\script>this.someGlobalVariable += $("#newByAppend").size()<\/script></div>'
          )
          t.assertIdentical(1, window.someGlobalVariable)
        } finally {
          delete window.someGlobalVariable
        }
      },

      testNoEvalWithSrc: function (t) {
        try {
          window.someGlobalVariable = false
          $('<\script src="remote.js">window.someGlobalVariable = true<\/script>').appendTo('body')
          t.assert(!window.someGlobalVariable, 'expected SCRIPT with src not to be evaled')
        } finally {
          delete window.someGlobalVariable
        }
      },

      testHtmlEval: function (t) {
        window.someGlobalVariable = 0
        try {
          $('<div>').appendTo('#fixtures').html(
            '<div><b id="newByHtml">Hi</b>' +
            '<\script>this.someGlobalVariable += $("#newByHtml").size()<\/script></div>'
          )
          t.assertIdentical(1, window.someGlobalVariable)
        } finally {
          delete window.someGlobalVariable
        }
      },

      testPrependEval: function (t) {
        window.someGlobalVariable = 0
        try {
          $('<div>').appendTo('#fixtures').prepend(
            '<b id="newByPrepend">Hi</b>' +
            '<\script>this.someGlobalVariable += $("#newByPrepend").size()<\/script>'
          )
          t.assertIdentical(1, window.someGlobalVariable)
        } finally {
          delete window.someGlobalVariable
        }
      },

      testAppendTemplateNonEval: function (t) {
        try {
          window.someGlobalVariable = true
          $('<' + 'script type="text/template">window.someGlobalVariable = false</script' + '>').appendTo('body')
          t.assert(window.someGlobalVariable)

          window.someGlobalVariable = true
          $('<' + 'script type="text/template">this.someGlobalVariable = false</script' + '>').appendTo('body')
          t.assert(window.someGlobalVariable)
        } finally {
          delete window.someGlobalVariable
        }
      },

      testHtmlTemplateNonEval: function (t) {
        try {
          window.someGlobalVariable = true
          $('<div></div>').appendTo('body')
            .html('<' + 'script type="text/template">window.someGlobalVariable = false</script' + '>')
          t.assert(window.someGlobalVariable)
        } finally {
          delete window.someGlobalVariable
        }
      },

      testRemove: function(t) {
        var el = $('<div>').appendTo(document.body)
        t.assertLength(1, el.parent())
        t.assertIdentical(el, el.remove())
        t.assertLength(0, el.parent())
        t.assertIdentical(el, el.remove())  //=> ensure an error isn't raised
      },

      testAddRemoveClass: function(t){
        var el = $('#some_element').get(0)

        $('#some_element').addClass('green')
        t.assertEqual('green', el.className)
        $('#some_element').addClass('green')
        t.assertEqual('green', el.className)
        $('#some_element').addClass('red')
        t.assertEqual('green red', el.className)
        $('#some_element').addClass('blue red')
        t.assertEqual('green red blue', el.className)
        $('#some_element').removeClass('green blue')
        t.assertEqual('red', el.className)

        $('#some_element').attr('class', ' red green blue ')
        t.assertEqual(' red green blue ', el.className) // sanity check that WebKit doesn't change original input
        $('#some_element').removeClass('green')
        t.assertEqual('red blue', el.className)

        //addClass with function argument
        $('#some_element').addClass(function(idx,classes){
          //test the value of "this"
          t.assertEqualCollection($('#some_element'), $(this))
          //test original classes are being passed
          t.assertEqual('red blue', this.className)
          return "green"
        })
        t.assertEqual('red blue green', el.className)

        // addClass with no argument
        t.assertEqualCollection($('#some_element'), $('#some_element').addClass())
        t.assertEqual('red blue green', el.className)
        t.assertEqualCollection($('#some_element'), $('#some_element').addClass(''))
        t.assertEqual('red blue green', el.className)

        //removeClass with function argument
        $('#some_element').removeClass(function(idx,classes){
          //test the value of "this"
          t.assertEqualCollection($('#some_element'), $(this))
          //test original classes are being passed
          t.assertEqual('red blue green', this.className)
          return "blue"
        })
        t.assertEqual('red green', el.className)

        $('#some_element').removeClass()
        t.assertEqual('', el.className)
      },

      testHasClass: function(t){
        var el = $('#some_element')
        el.addClass('green')

        t.assert(el.hasClass('green'))
        t.assert(!el.hasClass('orange'))

        el.addClass('orange')
        t.assert(el.hasClass('green'))
        t.assert(el.hasClass('orange'))

        el = $(document.body)
        t.assert(!el.hasClass('orange'), "body shouldn't have the class")
        el = el.add('#some_element')
        t.assert(el.hasClass('orange'), "an element in collection has the class")

        t.assertFalse(el.hasClass())
        t.assertFalse(el.hasClass(''))
      },

      testHasClassEmpty: function(t){
        var z = $('#doesnotexist')
        t.assertEqual(0, z.size())
        t.assertFalse(z.hasClass('a'))
      },

      testToggleClass: function(t){
        var el = $('#toggle_element').removeClass()

        t.assertIdentical(el, el.toggleClass('green'))
        t.assertTrue(el.hasClass('green'))
        t.assertFalse(el.hasClass('orange'))

        el.toggleClass('orange')
        t.assertTrue(el.hasClass('green'))
        t.assertTrue(el.hasClass('orange'))

        el.toggleClass('green')
        t.assertFalse(el.hasClass('green'))
        t.assertTrue(el.hasClass('orange'))

        el.toggleClass('orange')
        t.assertFalse(el.hasClass('green'))
        t.assertFalse(el.hasClass('orange'))

        el.toggleClass('orange green')
        t.assertTrue(el.hasClass('orange'))
        t.assertTrue(el.hasClass('green'))

        el.toggleClass('orange green blue')
        t.assertFalse(el.hasClass('orange'))
        t.assertFalse(el.hasClass('green'))
        t.assertTrue(el.hasClass('blue'))

        el.removeClass()

        el.toggleClass('orange', false)
        t.assertFalse(el.hasClass('orange'))
        el.toggleClass('orange', false)
        t.assertFalse(el.hasClass('orange'))

        el.toggleClass('orange', true)
        t.assertTrue(el.hasClass('orange'))
        el.toggleClass('orange', true)
        t.assertTrue(el.hasClass('orange'))

        //function argument
        el.toggleClass(function(idx,classes){
          t.assertIdentical(el.get(0), this)
          //test original classes are being passed
          t.assertEqual('orange', this.className)
          return "brown"
        })
        t.assertTrue(el.hasClass('brown'))

        el.toggleClass(function(idx,classes){
          return "yellow"
        }, false)
        t.assertFalse(el.hasClass('yellow'))

        el.toggleClass(function(idx,classes){
          return "yellow"
        }, true)
        t.assert(el.hasClass('yellow'))

        // no/empty argument
        t.assertIdentical(el, el.toggleClass())
        t.assertEqual('orange brown yellow', el.get(0).className)
        t.assertIdentical(el, el.toggleClass(''))
        t.assertEqual('orange brown yellow', el.get(0).className)
      },

      testClassSVG: function(t){
        var svg = $('svg')
        t.assert(!svg.hasClass('foo'))
        svg.addClass('foo bar')
        t.assert(svg.hasClass('foo'))
        t.assert(svg.hasClass('bar'))
        svg.removeClass('foo')
        t.assert(!svg.hasClass('foo'))
        t.assert(svg.hasClass('bar'))
        svg.toggleClass('bar')
        t.assert(!svg.hasClass('foo'))
        t.assert(!svg.hasClass('bar'))
      },

      testIndex: function(t){
        t.assertEqual($("p > span").index("#nay"), 2)
        t.assertEqual($("p > span").index(".yay"), 0)
        t.assertEqual($("span").index("span"), 0)
        t.assertEqual($("span").index("boo"), -1)

        t.assertEqual($('#index_test > *').eq(-1).index(), 1)
      },

      testBoolAttr: function (t) {
        t.assertEqual($('#BooleanInput').attr('required'), true)
        t.assertEqual($('#BooleanInput').attr('non_existant_attr'), undefined)
      },

      testDocumentReady: function (t) {
        // Check that if document is already loaded, ready() immediately executes callback
        var arg1, arg2, arg3, arg4, fired = false
        $(function (Z1) {
          arg1 = Z1
          $(document).ready(function (Z2) {
            arg2 = Z2
            $(document).on('ready', function (Z3) {
              arg3 = Z3
              $(document).on('foo ready bar', function (Z4) {
                arg4 = Z4
                fired = true
              })
            })
          })
        })
        t.assertTrue(fired)
        t.assertIdentical(Zepto, arg1)
        t.assertIdentical(Zepto, arg2)
        t.assertIdentical(Zepto, arg3)
        t.assertIdentical(Zepto, arg4)
      },

      testSlice: function (t) {
        var $els = $("#slice_test div")
        t.assertEqual($els.slice().length, 3)
        t.assertEqual(typeof $els.slice().ready, 'function')
        t.assertEqual($els.slice(-1)[0].className, 'slice3')
      },

      testScrollTop: function(t) {
        var $window = $(window), $body = $(document.body)
        t.assert($window.scrollTop() >= 0)
        t.assert($body.scrollTop() >= 0)

        t.assertIdentical($window.scrollTop(20), $window)
        t.assertIdentical($body.scrollTop(20),   $body)
      },

      testScrollLeft: function(t) {
        var $window = $(window), $body = $(document.body)
        t.assert($window.scrollLeft() >= 0)
        t.assert($body.scrollLeft() >= 0)

        t.assertIdentical($window.scrollLeft(20), $window)
        t.assertIdentical($body.scrollLeft(20),   $body)
      },

      testSort: function(t){
        var els = $(['eight', 'nine', 'ten', 'eleven'])
        var result = els.sort(function(a,b){ return b.length > a.length ? -1 : 1 })
        t.assertIdentical(els, result)
        t.assertEqual(4, result.size())
        t.assertEqualCollection(['ten', 'nine', 'eight', 'eleven'], result)
      }
    })

    Evidence('EventTest', {
      tearDown: function(){
        $('*').unbind()
      },

      testBind: function(t){
        var counter = 0
        $(document.body).bind('click', function(){ counter++ })
        click($('#some_element').get(0))
        t.assertEqual(1, counter)

        counter = 0
        $('#some_element').bind('click mousedown', function(){ counter++ })
        click($('#some_element').get(0))
        mousedown($('#some_element').get(0))
        t.assertEqual(3, counter) // 1 = body click, 2 = element click, 3 = element mousedown
      },

      testBindWithObject: function(t){
        var counter = 0, keyCounter = 0, el = $('#some_element'),
          eventData = {
            click: function(){ counter++ },
            keypress: function(){ keyCounter++ }
          }

        $(document.body).bind(eventData)

        el.trigger('click')
        el.trigger('click')
        t.assertEqual(2, counter)
        el.trigger('keypress')
        t.assertEqual(1, keyCounter)

        $(document.body).unbind({ keypress: eventData.keypress })

        el.trigger('click')
        t.assertEqual(3, counter)
        el.trigger('keypress')
        t.assertEqual(1, keyCounter)
      },

      testBindContext: function(t){
        var context, handler = function(){
          context = $(this)
        }
        $('#empty_test').bind("click",handler)
        $('#empty_test').bind("mousedown",handler)
        click($('#empty_test').get(0))
        t.assertEqualCollection($('#empty_test'), context)
        context = null
        mousedown($('#empty_test').get(0))
        t.assertEqualCollection($('#empty_test'), context)
      },

      testBindWithCustomArgument: function(t) {
        var data, numArgs, counter = 0,
            handler = function(ev, arg) {
              numArgs = arguments.length,
              data = ev.data
              counter = arg.counter
            }

        $('#some_element').bind('custom', handler)
        $('#some_element').trigger('custom', { counter: 10 })
        t.assertEqual(10, counter)
        t.assertEqual(2, numArgs)
        t.assertUndefined(data)
      },

      testBindPreventDefault: function (t) {
        var link = $('<a href="#"></a>'),
            prevented = false

        link
          .appendTo('body')
          .bind('click', function () {
            return false
          })
          .bind('click', function (e) {
            prevented = e.isDefaultPrevented()
          })
          .trigger('click')

        t.assert(prevented)
      },

      testCreateEventObject: function(t){
        var e = $.Event('custom')
        t.assertEqual('custom', e.type)

        var e2 = new $.Event('custom')
        t.assertEqual('custom', e2.type)

        var e3 = $.Event('custom', {customKey: 'customValue'})
        t.assertEqual('custom', e3.type)
        t.assertEqual('customValue', e3.customKey)

        var e4 = $.Event('custom', {bubbles: false})
        t.assertFalse(e4.bubbles)

        var e5 = $.Event({ type: 'keyup', keyCode: 40 })
        t.assertEqual('keyup', e5.type)
        t.assertEqual(40, e5.keyCode)
      },

      testTriggerObject: function(t){
        var el = $('#some_element'),
            eventType, eventCode

        el.on('keyup', function(e){
          eventType = e.type
          eventCode = e.keyCode
        })
        el.trigger({ type: 'keyup', keyCode: 40 })

        t.assertEqual('keyup', eventType)
        t.assertEqual(40, eventCode)
      },

      testTriggerEventObject: function(t){
        var data, counter = 0,
            customEventKey = 0

        var handler = function(ev,customData) {
          data = ev.data
          counter = customData.counter
          customEventKey = ev.customKey
        }

        var customEventObject = $.Event('custom', { customKey: 20 })

        $('#some_element').bind('custom', handler)
        $('#some_element').trigger(customEventObject, { counter: 10 })

        t.assertEqual(10, counter)
        t.assertEqual(20, customEventKey)
        t.assertUndefined(data)
      },

      testTriggerEventCancelled: function(t){
        var event = $.Event('custom'),
          element = $('<div/>'),
          isDefaultPrevented = false

        t.refute(event.isDefaultPrevented())

        element.bind('custom', function(e){
          e.preventDefault()
          isDefaultPrevented = e.isDefaultPrevented()
        })

        element.trigger(event)

        t.assertTrue(event.isDefaultPrevented())
        t.assertTrue(isDefaultPrevented)
      },

      testTriggerHandler: function(t){
        t.assertUndefined($('doesnotexist').triggerHandler('submit'))

        var form = $('#trigger_handler form').get(0)
        $('#trigger_handler').bind('submit', function(e) {
          t.fail("triggerHandler shouldn't bubble")
        })

        var executed = []
        $(form).bind('submit', function(e) {
          executed.push("1")
          t.assertEqual(form, e.target)
          return 1
        })
        $(form).bind('submit', function(e) {
          executed.push("2")
          t.assertEqual(form, e.target)
          e.stopImmediatePropagation()
          return 2
        })
        $(form).bind('submit', function(e) {
          t.fail("triggerHandler shouldn't continue after stopImmediatePropagation")
        })
        t.assertIdentical(2, $(form).triggerHandler('submit'))
        t.assertEqual('1 2', executed.join(' '))
      },

      testUnbind: function(t){
        var counter = 0, el = $('#another_element').get(0)
        var handler = function(){ counter++ }
        $('#another_element').bind('click mousedown', handler)
        click(el)
        mousedown(el)
        t.assertEqual(2, counter)

        $('#another_element').unbind('click', handler)
        click(el)
        t.assertEqual(2, counter)
        mousedown(el)
        t.assertEqual(3, counter)

        $('#another_element').unbind('mousedown')
        mousedown(el)
        t.assertEqual(3, counter)

        $('#another_element').bind('click mousedown', handler)
        click(el)
        mousedown(el)
        t.assertEqual(5, counter)

        $('#another_element').unbind()
        click(el)
        mousedown(el)
        t.assertEqual(5, counter)
      },

      testUnbindWithNamespace: function(t){
        var count = 0
        $("#namespace_test").bind("click.bar", function() { count++ })
        $("#namespace_test").bind("click.foo", function() { count++ })
        $("#namespace_test").bind("mousedown.foo.bar", function() { count++ })

        $("#namespace_test").trigger("click")
        t.assertEqual(2, count)

        $("#namespace_test").unbind("click.baz")
        $("#namespace_test").trigger("click")
        t.assertEqual(4, count)

        $("#namespace_test").unbind("click.foo")
        $("#namespace_test").trigger("click")
        t.assertEqual(5, count)

        $("#namespace_test").trigger("mousedown")
        t.assertEqual(6, count)

        $("#namespace_test").unbind(".bar")
        $("#namespace_test").trigger("click").trigger("mousedown")
        t.assertEqual(6, count)
      },

      testDelegate: function(t){
        var counter = 0, pcounter = 0
        $(document.body).delegate('#some_element', 'click', function(){ counter++ })
        $('p').delegate('span.yay', 'click', function(){ counter++ })
        $(document.body).delegate('p', 'click', function(){ pcounter++ })

        click($('#some_element').get(0))
        t.assertEqual(1, counter)

        click($('span.yay').get(0))
        t.assertEqual(2, counter)

        click($('span.nay').get(0))
        t.assertEqual(2, counter)

        click($('p').get(0))
        t.assertEqual(3, pcounter)
      },

      testDelegateBlurFocus: function(t) {
        var counter = 0
        $('#delegate_blur_test').delegate('input', 'blur', function(){ counter++ })

        $('#delegate_blur_test').find('input').focus()
        $('#delegate_blur_test').find('input').blur()
        t.assertEqual(1, counter)

        $('#delegate_blur_test').find('input').focus()
        $('#delegate_blur_test').find('input').blur()
        t.assertEqual(2, counter)

        $('#delegate_focus_test').delegate('input', 'focus', function(){ counter++ })

        $('#delegate_focus_test').find('input').focus()
        $('#delegate_focus_test').find('input').blur()
        t.assertEqual(3, counter)

        $('#delegate_focus_test').find('input').focus()
        $('#delegate_focus_test').find('input').blur()
        t.assertEqual(4, counter)
      },

      testDelegateNamespacedBlurFocus: function(t) {
        var counter = 0
        $('#delegate_blur_test').delegate('input', 'blur.namespace_test', function(){ counter++ })

        $('#delegate_blur_test').find('input').focus()
        $('#delegate_blur_test').find('input').blur()
        t.assertEqual(1, counter)

        $('#delegate_blur_test').find('input').focus()
        $('#delegate_blur_test').find('input').blur()
        t.assertEqual(2, counter)

        $('#delegate_focus_test').delegate('input', 'focus.namespace_test', function(){ counter++ })

        $('#delegate_focus_test').find('input').focus()
        $('#delegate_focus_test').find('input').blur()
        t.assertEqual(3, counter)

        $('#delegate_focus_test').find('input').focus()
        $('#delegate_focus_test').find('input').blur()
        t.assertEqual(4, counter)
      },

      testUndelegateNamespacedBlurFocus: function(t) {
        var el, counter = 0

        el = $('#delegate_blur_test')

        el.delegate('input', 'blur.test', function(){ counter++ })
        el.find('input').focus().blur()
        t.assertEqual(1, counter, 'expected handler to be triggered')

        el.undelegate('input', '.test')
        el.find('input').focus().blur()
        t.assertEqual(1, counter, 'expected handler to unbind')

        el = $('#delegate_focus_test')

        el.delegate('input', 'focus.test', function(){ counter++ })
        el.find('input').focus().blur()
        t.assertEqual(2, counter, 'expected handler to be triggered')

        el.undelegate('input', '.test')
        el.find('input').focus().blur()
        t.assertEqual(2, counter, 'expected handler to unbind')
      },

      testDelegateReturnFalse: function(t){
        $(document.body).delegate('#link_that_will_be_prevented', 'click', function(){
          return false
        })

        var event = $.Event('click')
        $('#link_that_will_be_prevented').trigger(event)

        t.assertTrue(event.isDefaultPrevented())

        t.pause()
        setTimeout(function(){
          t.resume(function(){
            var text = $('#link_target_iframe')[0].contentDocument.body.textContent
            t.assert(!text.match(/Hello from iframe/))
          })
        }, 500)
      },

      testDelegateReturnValueShouldntPreventDefault: function(t){
        $(document.body).delegate('#link_that_will_be_prevented', 'click', function(){
        })

        var event = $.Event('click')
        $('#link_that_will_be_prevented').trigger(event)

        t.assertFalse(event.isDefaultPrevented())

        t.pause()
        setTimeout(function(){
          t.resume(function(){
            var text = $('#link_target_iframe')[0].contentDocument.body.textContent
            t.assert(text.match(/Hello from iframe/))
          })
        }, 500)
      },

      testDelegateWithObject: function(t){
        var counter = 0, received, el = $('p').first(),
          eventData = {
            click: function(){ counter++ },
            custom: function(e, arg){ received = arg }
          }

        $(document.body).delegate('p', eventData)

        el.trigger('click')
        t.assertEqual(1, counter)
        el.trigger('click')
        t.assertEqual(2, counter)
        el.trigger('custom', 'boo')
        t.assertEqual('boo', received)

        $(document.body).undelegate('p', {custom: eventData.custom})

        el.trigger('click')
        t.assertEqual(3, counter)
        el.trigger('custom', 'bam')
        t.assertEqual('boo', received)
      },

      testDelegateWithCustomArgument: function(t) {
        var received
        $(document).delegate('#some_element', 'custom', function(e, arg, more){ received = arg + more })
        $('p').delegate('span.yay', 'custom', function(e, arg){ received = arg })
        $(document).delegate('p', 'custom', function(e, arg){ received = arg })

        $('#some_element').trigger('custom', 'one')
        t.assertEqual('oneundefined', received)
        $('#some_element').trigger('custom', ['one', 'two'])
        t.assertEqual('onetwo', received)

        $('span.yay').trigger('custom', 'boom')
        t.assertEqual('boom', received)
        $('span.yay').trigger('custom', ['bam', 'boom'])
        t.assertEqual('bam', received)

        $('span.nay').trigger('custom', 'noes')
        t.assertEqual('noes', received)

        $('p').first().trigger('custom', 'para')
        t.assertEqual('para', received)
      },

      testDelegateEventProxy: function(t){
        var content
        $('div#delegate_test').delegate('span.second-level', 'click', function(e){
          t.assertEqual($('span.second-level').get(0), this)
          t.assertEqual($('span.second-level').get(0), e.currentTarget)
          t.refuteEqual($('span.second-level').get(0), e.originalEvent.currentTarget)
          t.assertEqual($('div#delegate_test').get(0), e.liveFired)
          content = $(this).html()
        })
        click($('span.second-level').get(0))
        t.assertEqual('hi', content)

        var fired = false
        if (window.location.hash.length) window.location.hash = ''
        $('div#delegate_test').html('<a href="#foo"></a>')
        $('div#delegate_test').delegate('a', 'click', function(e){
          e.preventDefault()
          fired = true
        })
        click($('div#delegate_test a').get(0))
        t.assert(fired)
        t.refuteEqual('#foo', window.location.hash)

        fired = false
        if (window.location.hash.length) window.location.hash = ''
        $('div#delegate_test').html('<a href="#bar"></a>')
        $('div#delegate_test a').trigger('click')
        t.assert(fired)
        t.refuteEqual('#bar', window.location.hash)
      },

      testUndelegate: function(t){
        var count = 0, handler = function() { count++ }
        $("#undelegate_test").bind("click mousedown", handler)
        $("#undelegate_test").delegate("span.first-level", "click mousedown", handler)
        $("#undelegate_test").delegate("span.second-level", "click mousedown", handler)
        $("#undelegate_test span.second-level").trigger("click")
        t.assertEqual(3, count)

        $("#undelegate_test").undelegate("span.second-level", "click", handler)
        $("#undelegate_test span.second-level").trigger("click")
        t.assertEqual(5, count)

        $("#undelegate_test").undelegate("span.first-level")
        $("#undelegate_test span.second-level").trigger("click")
        t.assertEqual(6, count)

        $("#undelegate_test").unbind("click")
        $("#undelegate_test span.second-level").trigger("click")
        t.assertEqual(6, count)

        $("#undelegate_test span.second-level").trigger("mousedown")
        t.assertEqual(8, count)

        $("#undelegate_test").undelegate()
        $("#undelegate_test span.second-level").trigger("mousedown")
        t.assertEqual(8, count)
      },

      testLive: function(t){
        var counter = 0
        $('p.live').live('click', function(){ counter++ })

        $(document.body).append('<p class="live" id="live_1"></p>')
        $(document.body).append('<p class="live" id="live_2"></p>')

        click($('#live_1').get(0))
        click($('#live_2').get(0))

        $('p.live').remove()
        $(document.body).append('<p class="live" id="live_this_test"></p>')

        $('p.live').live('click', function(){
          t.assertEqual(document.getElementById('live_this_test'), this)
        })
        click($('#live_this_test').get(0))

        t.assertEqual(3, counter)
      },

      testDie: function(t){
        var count = 0, handler = function() { count++ }
        $("#another_element").live("click mousedown", handler)
        $("#another_element").trigger("click")
        t.assertEqual(1, count)

        $("#another_element").die("click", handler)
        $("#another_element").trigger("click")
        t.assertEqual(1, count)

        $("#another_element").trigger("mousedown")
        t.assertEqual(2, count)

        $("#another_element").die()
        $("#another_element").trigger("mousedown")
        t.assertEqual(2, count)
      },

      testOn: function(t){
        var el = $('#some_element'), node = el.get(0), ret,
          bindTriggered = 0, delegateTriggered = 0

        ret = el.on('click', function(e){
          bindTriggered++
          t.assertIdentical(node, this)
        })
          .on({ click: function(){bindTriggered++} })
        t.assertIdentical(el, ret)

        ret = $(document.body).on('click', 'div', function(e){
          delegateTriggered++
          t.assertIdentical(node, this)
        })
          .on({ click: function(){delegateTriggered++} }, '*[id^=some]')
        t.assertIdentical(document.body, ret.get(0))

        click(node)
        t.assertEqual(2, bindTriggered, "bind handlers")
        t.assertEqual(2, delegateTriggered, "delegate handlers")
      },

      testOnReturnFalse: function(t){
        var el = $('#some_element')

        el.on('click', function(){
          setTimeout(function(){
            t.resume(function(){})
          }, 10)
          t.assert(true, "should have been called")
          return false
        })
        $(document.body).on('click', function(){
          t.refute(true, "the event should have been stopped")
        })

        t.pause()
        click(el.get(0))
      },

      testOff: function(t){
        var el = $('#some_element'), bindTriggered = 0, delegateTriggered = 0,
          handler = function(){ bindTriggered++ }

        el.bind('click', handler).bind('click', function(){ bindTriggered++ })
        el.live('click', function(){ delegateTriggered++ })

        click(el.get(0))
        t.assertEqual(2, bindTriggered, "bind handlers before unbind")
        t.assertEqual(1, delegateTriggered, "delegate handlers before unbind")

        el.off('click', handler)
        $(document.body).off('click', '#some_element')

        click(el.get(0))
        t.assertEqual(3, bindTriggered, "bind handlers")
        t.assertEqual(1, delegateTriggered, "delegate handlers")
      },

      testOne: function(t){
        var counter = 0, context, received, el = $('#some_element')
        $(document.body).one('click', function(e, arg, more){
          context = this
          counter++
          received = arg + more
          t.assertIn('preventDefault', e)
          return false
        })

        var evt = $.Event('click')
        el.trigger(evt, ['one', 'two'])
        t.assertEqual(1, counter)
        t.assertEqual('onetwo', received)
        t.assertIdentical(document.body, context)
        t.assertTrue(evt.isDefaultPrevented())

        el.trigger('click')
        t.assertEqual(1, counter, "the event handler didn't unbind itself")
      },

      testOneWithObject: function(t){
        var counter = 0, el = $('#some_element')
        $(document.body).one({
          click: function() { counter++ },
          custom: function() { counter-- }
        })

        el.trigger('click')
        t.assertEqual(1, counter)
        el.trigger('click')
        t.assertEqual(1, counter)

        el.trigger('custom')
        t.assertEqual(0, counter)
        el.trigger('custom')
        t.assertEqual(0, counter)
      },

      testDOMEventWrappers: function(t){
        var events = ('blur focus focusin focusout load resize scroll unload click dblclick '+
          'mousedown mouseup mousemove mouseover mouseout '+
          'change select keydown keypress keyup error').split(' ')

        var el = $('#another_element'), count = 0

        events.forEach(function(event){
          t.assertTrue($.isFunction(el[event]), 'event type: ' + event)
        })

        el.click(function(){ count++ })
        click(el.get(0))

        t.assertEqual(1, count)
      },

      testCustomEvents: function (t) {
        var el = $(document.body)

        el.bind('custom', function(evt, a, b) {
          t.assertEqual(a, 1)
          t.assertEqual(b, 2)
          el.unbind()
        })
        el.trigger('custom', [1, 2])

        el.bind('custom', function(evt, a) {
          t.assertEqual(a, 1)
          el.unbind()
        })
        el.trigger('custom', 1)

        var eventData = {z: 1}
        el.bind('custom', function(evt, a) {
          t.assertEqual(a, eventData)
          el.unbind()
        })
        el.trigger('custom', eventData)
      },

      testSpecialEvent: function (t) {
        var clickEvent     = $.Event('click'),
            mouseDownEvent = $.Event('mousedown'),
            mouseUpEvent   = $.Event('mouseup'),
            mouseMoveEvent = $.Event('mousemove'),
            submitEvent    = $.Event('submit')

        t.assertEqual(MouseEvent, clickEvent.constructor)
        t.assertEqual(MouseEvent, mouseDownEvent.constructor)
        t.assertEqual(MouseEvent, mouseUpEvent.constructor)
        t.assertEqual(MouseEvent, mouseMoveEvent.constructor)
        t.assertEqual(Event,      submitEvent.constructor)
      }
    })
  })()
  </script>
</body>
</html>
